docraft
v0.1.0
Published
CLI tool that detects {{PLACEHOLDER}} fields in docx, odt, pages, pdf and markdown documents and fills them in interactively or via automation.
Maintainers
Readme
Docraft
Docraft is a cross-platform (Windows, macOS, Linux) command-line tool that scans a document
for placeholder fields — {{LIKE_THIS}} by default — and fills them in for you, either by
asking you interactively or by taking the values straight from the command line for
automation and scripting.
Features
- Detects placeholder fields such as
{{FULL_NAME}},{{DATE}},{{INVOICE_NUMBER}}in your documents. - Interactive mode by default: Docraft finds every field and asks you what to put in each one.
- Automation mode: pass values on the command line (or from a JSON file) and skip the prompts entirely — ideal for scripts and CI pipelines.
- Configurable delimiters: use
{{ }},[[ ]],%% %%, or anything else you like. - Multi-format support: Word (
.docx), OpenDocument Text (.odt), Apple Pages (.pages, macOS only), PDF (.pdf) and Markdown (.md).
Supported document formats
| Format | Extension | Notes |
| ----------------- | --------- | -------------------------------------------------------------------------- |
| Markdown | .md | Plain text replacement. |
| Word | .docx | Reads/writes the document's XML directly. |
| OpenDocument Text | .odt | Reads/writes the document's XML directly. |
| Apple Pages | .pages | macOS only, requires Pages.app. See limitations. |
| PDF | .pdf | Best-effort text overlay. See limitations. |
Installation
Docraft is published on npm and meant to be installed globally:
npm install -g docraftThis makes the docraft command available on Windows, macOS and Linux.
Usage
docraft <file> [options]Interactive mode (default)
docraft contract.docxDocraft scans contract.docx for every {{FIELD}} placeholder, asks you for a value for
each one, and writes the result to contract.filled.docx (next to the original file).
Automation mode
Pass field values directly to skip the prompts — handy for scripts and CI:
docraft contract.docx \
--field NAME="Ada Lovelace" \
--field DATE=2026-07-27 \
--non-interactive \
--output contract-ada.docxYou can also provide values from a JSON file:
docraft contract.docx --data ./values.json --non-interactive{
"NAME": "Ada Lovelace",
"DATE": "2026-07-27"
}If a field has no value from --field/--data and --non-interactive was passed, Docraft
fails with a clear error listing the missing fields instead of guessing.
CLI options
| Option | Description |
| ------------------------- | -------------------------------------------------------------------- |
| -o, --output <path> | Output file path (default: <name>.filled.<ext> next to the input). |
| -f, --field <key=value> | Set a field value directly; repeatable. |
| --data <path> | Path to a JSON file of { "FIELD": "value" } pairs. |
| --non-interactive | Never prompt; fail if a detected field has no value. |
| --open-delim <string> | Override the opening delimiter for this run only. |
| --close-delim <string> | Override the closing delimiter for this run only. |
| -y, --yes | Overwrite the output file without asking for confirmation. |
Configuration
By default, Docraft looks for fields wrapped in {{ and }}. You can change these
delimiters globally:
docraft config set openDelimiter "[["
docraft config set closeDelimiter "]]"Other useful commands:
docraft config get # print the full configuration
docraft config get openDelimiter
docraft config path # print where the configuration file livesThe configuration file lives in your platform's standard config directory (for example
~/.config/docraft/config.json on Linux, ~/Library/Preferences/docraft/config.json on
macOS, or %APPDATA%\docraft\config.json on Windows) and can also be edited by hand.
Per-run overrides via --open-delim/--close-delim always take priority over the saved
configuration.
Known limitations
- PDF: text is extracted and replaced on a best-effort basis. A placeholder is only
replaced when it is fully contained in a single text run inside the PDF (the common case
for PDFs exported from Word/Google Docs/LibreOffice). The original font, color and style
are not preserved — Docraft masks the original text and draws the replacement in
Helvetica. If a placeholder is split across multiple text runs by the exporting
application, Docraft reports it as a warning instead of silently leaving it half-filled.
Importantly, the original placeholder text is only visually covered, not removed from the
PDF's content stream: it can still show up when selecting, copying or searching text in
the output file (e.g. with
pdftotext), even though it's invisible when viewing or printing the document. Don't rely on this for redacting sensitive information. - Apple Pages:
.pagessupport requires macOS with Pages.app installed, because Docraft automates Pages itself (via AppleScript) to convert the document to.docx, fill it using the same engine as Word documents, and convert the result back to.pages. It will not work on Windows or Linux, or on a Mac without Pages installed. - Word/OpenDocument autocorrect: if your word processor's autocorrect feature splits a placeholder into multiple runs of text (rare, but possible with smart quotes/formatting), Docraft may not detect it. Disabling autocorrect while typing placeholders avoids this.
Development
git clone https://github.com/mateocallec/docraft.git
cd docraft
scripts/install.sh # installs dependencies
scripts/run.sh <file> [options] # run docraft from source, without building
scripts/format.sh # format the codebase with PrettierOther useful npm scripts:
npm run build— compile TypeScript todist/.npm run dev -- <file>— run the CLI from source viatsx.npm start -- <file>— run the compiled CLI fromdist/.
Contributing
Contributions are welcome! Please read the Code of Conduct before opening an issue or pull request, and see CONTRIBUTORS.md to add yourself once your first pull request is merged. Planned work is tracked in ROADMAP.md, and past changes are listed in CHANGELOG.md.
Security
Please see SECURITY.md for how to responsibly report a vulnerability.
License
Docraft is released under the MIT License.
