disqus-wxr-middleware
v0.3.0
Published
Exports a Disqus forum to a WordPress WXR file through the Disqus API (client-run tool, no WordPress required).
Maintainers
Readme
disqus-wxr-middleware
Exports a Disqus forum to a WordPress WXR file through the Disqus API. A standalone command-line tool, run by the client with their own Disqus credentials — no dependency on any third-party infrastructure.
The generated WXR file is a standard WordPress export (WXR 1.2): it can be imported as-is into GraphComment through the WordPress import flow.
Table of contents
- Requirements
- Installation
- Usage
- Options
- Resuming after an interruption
- Limits & duration
- What to do with the WXR file
- Programmatic API
- Security & data
- GDPR — read before exporting
- Contributing
- License
Requirements
- Node.js ≥ 18 (the tool uses native
fetch, no external network dependency). - A Disqus application (disqus.com/api/applications/)
owned by the forum owner, with the email permission granted
(read-only "Read" access is enough for the export). From it you need:
- the secret key (
api_secret) — required; - the access token — required;
- the public key (
api_key) — optional (no call made by the tool uses it).
- the secret key (
The email permission is what allows the API to return the commenters' real addresses. Without it, the export still works but emails will be missing. See GDPR before enabling this scope.
Installation
No permanent installation is needed — the tool runs through npx:
npx disqus-wxr-middleware --helpFor a project-local installation:
npm install disqus-wxr-middlewareUsage
# Export a forum to a WXR file
npx disqus-wxr-middleware --forum <shortname> --out ./export.wxr.xml \
--api-secret <SECRET> --access-token <TOKEN>
# Credentials can also be passed through the environment
DISQUS_API_SECRET=<SECRET> DISQUS_ACCESS_TOKEN=<TOKEN> \
npx disqus-wxr-middleware --forum <shortname> --out ./export.wxr.xml
# Validate the configuration without running the export (no API call)
npx disqus-wxr-middleware --forum <shortname> --api-secret <SECRET> --access-token <TOKEN> --dry-runThe <shortname> is your Disqus forum's short identifier (the one in the URL
https://<shortname>.disqus.com/).
Options
| Option | Description | Default |
|---|---|---|
| --forum <shortname> | Shortname of the Disqus forum to export (required). | — |
| --out <file.xml> | Output WXR file. | ./disqus-export.wxr.xml |
| --api-secret <secret> | Disqus secret key (or env DISQUS_API_SECRET) — required. | — |
| --access-token <token> | Disqus access token (or env DISQUS_ACCESS_TOKEN) — required. | — |
| --api-key <key> | Disqus public key (or env DISQUS_API_KEY) — optional, unused. | — |
| --resume | Resumes the export from the last checkpoint (see below). | off |
| --rate-budget <n> | API request budget per hour (Disqus rate limit). | 1000 |
| --max-buffer <n> | Maximum number of comments held in memory before flushing to disk. | 50000 |
| --dry-run | Validates the configuration without running the export (no API call). | off |
| -v, --version | Prints the version and exits. | — |
| --help | Prints the full help. | — |
npx disqus-wxr-middleware --help lists all up-to-date options.
Resuming after an interruption
A large forum can take hours, or even days to retrieve (the Disqus API rate limit spreads the export over time — see Limits & duration). An interruption (network, machine shutdown, temporarily exhausted Disqus quota) must not force you to start over.
Re-run the same command with --resume: the export picks up where it
stopped, without re-downloading or duplicating already-exported comments.
npx disqus-wxr-middleware --forum <shortname> --out ./export.wxr.xml \
--api-secret <SECRET> --access-token <TOKEN> --resumeLimits & duration
The channel that returns emails (the Disqus API) is also the one that scales the worst. The API is capped at 1000 requests per hour, and each request returns at most 100 comments — a maximum throughput of ~100,000 comments per hour.
| Forum size | Minimum export duration | |---|---| | 100,000 comments | ~1 h | | 1,000,000 comments | ~10 h | | 5,000,000 comments | ~2 days | | 10,000,000 comments | ~4 days |
The tool handles the rate limit automatically (throttling, recovery after a 429)
and spreads requests across hourly windows. For a very large forum, combine with
--resume to withstand interruptions.
History goes back ~5 years. The Disqus API caps how far back history can be retrieved to roughly 5 years: older comments may not be exportable.
What to do with the WXR file
The generated .wxr.xml file is a standard WordPress export (WXR 1.2). Import
it into GraphComment through the WordPress import flow (the same one used for a
regular WordPress export): the Disqus threads and comments are recreated there,
preserving the reply hierarchy.
Programmatic API
Besides the CLI, the package exposes a programmatic entry point so it can be driven from another Node project (for example a hosted export service):
// ESM-only package — a CommonJS project MUST use dynamic import (never `require()`).
const { runExport, createWxrWriter, createLogger } = await import('disqus-wxr-middleware');
const logger = createLogger();
const stats = await runExport({
config: {
forum: 'my-forum',
out: 'export.wxr.xml',
apiSecret: process.env.DISQUS_API_SECRET,
accessToken: process.env.DISQUS_ACCESS_TOKEN,
},
logger,
});
// stats → { items, comments, orphanThreads, orphanComments, flushes, out }Exported functions: runExport, createDisqusClient, createWxrWriter,
createLogger (+ mask), and the checkpoint helpers (checkpointPath,
readCheckpoint, writeCheckpoint, deleteCheckpoint, CheckpointError).
loggermust expose six methods —error,warn,info,debug,progress,budget.createLogger()returns a compliant instance; pass your own only if it implements all six.createWritercan be injected intorunExportto stream the WXR somewhere other than a local file (createWxrWriteraccepts aWritablein place of a path).
Security & data
- Disqus credentials are never written to logs or error messages (systematic masking).
- The generated WXR file may contain plain-text emails (see
GDPR). The project's
.gitignorealready ignores sensitive outputs (*.wxr.xml,disqus-export*.xml,*.checkpoint.json) — never commit an export or a checkpoint to a public repository, and store them on a medium you control.
GDPR — read before exporting
⚠️ The Disqus API returns commenters' emails in plain text to the forum owner, whereas Disqus's public export omits them and the moderation interface only shows them obfuscated. Exporting these emails with this tool may therefore bypass an anonymization measure that Disqus otherwise applies.
This tool observes this API behavior; it takes no position on its lawfulness. As the data controller of your forum, it is your responsibility to verify:
- the legal basis for retrieving and storing these emails;
- the information given to the commenters whose data you retrieve;
- the appropriate retention period.
These obligations fall on the client running the tool, not on GraphComment. If you are migrating to GraphComment, refer to the legal guidance provided by your GraphComment contacts regarding email retention on the platform side.
Contributing
Contributions are welcome — see CONTRIBUTING.md.
License
MIT © 2026 Semiologic
