An Automated CLI for viewing, managing, importing, and exporting content for BookStack, the open-source documentation platform.
Use the CLI immediately without installing globally:
-
bunx
bunx @junovy/bookstack-cli books list
-
npx
npx @junovy/bookstack-cli books list
-
pnpm (dlx)
pnpx @junovy/bookstack-cli books list
Note: The published CLI binary uses Node to run. Ensure Node 18+ (or 20+) is available when using bunx/npx/pnpm dlx.
Install the CLI globally so bookstack is available on your PATH:
-
npm
npm i -g @junovy/bookstack-cli bookstack --help
-
pnpm
pnpm add -g @junovy/bookstack-cli bookstack --help
-
bun
bun add -g @junovy/bookstack-cli bookstack --help
(Requires Node on the system since the CLI shim uses Node.)
Before using the CLI, you need to configure your BookStack credentials:
-
Initialize a config file (optional if you prefer env vars):
bookstack config init
-
Edit the created
bookstack-config.jsonfile with your BookStack instance details:{ "url": "https://your-bookstack-instance.com", "tokenId": "your-token-id", "tokenSecret": "your-token-secret" }
You can also provide credentials via environment variables, a .env file, or other standard config formats.
- CLI flags:
--url,--token-id,--token-secret - Environment variables:
BOOKSTACK_URL,BOOKSTACK_TOKEN_ID,BOOKSTACK_TOKEN_SECRET - .env files in project root:
.env,.env.local - Config files (first found):
bookstack-config.json(existing default)bookstack.config.(json|yaml|yml|toml).bookstackrc[.(json|yaml|yml|toml)]or.bookstackrcpackage.jsonfield"bookstack": { ... }
Example .env:
BOOKSTACK_URL=https://your-bookstack-instance.com
BOOKSTACK_TOKEN_ID=your-token-id
BOOKSTACK_TOKEN_SECRET=your-token-secretTo point at a specific config file format/path:
bookstack -- --config ./bookstack.config.yaml list booksImport a single file:
bookstack import path/to/file.md --book "My Book"Import a directory (first-level folders become chapters; files become pages):
bookstack import path/to/directory --book "My Book"Import with specific format:
bookstack import content.html --book "Documentation" --format htmlDry run to see what would be imported:
bookstack import content/ --book "Test" --dry-runBooks:
bookstack books listChapters (requires a book ID, name, or slug):
bookstack chapters list --book <id|name|slug>Pages (optionally filter by book):
bookstack pages list
bookstack pages list --book <id|name|slug>
All list commands support `--json` for machine-readable output.Initialize config file:
bookstack config initShow current configuration:
bookstack config showGlobal options:
-u, --url <url>: BookStack base URL-i, --token-id <id>: BookStack API token ID-s, --token-secret <secret>: BookStack API token secret-c, --config <path>: Config file path (auto-detected if omitted)
Import options:
-b, --book <name>: Target book name or ID-f, --format <format>: Source format (markdown, html, json) - default: markdown--dry-run: Show what would be imported without making changes
For list commands, --book accepts ID, name, or slug.
- Markdown (
.md,.markdown) - HTML (
.html,.htm) - Plain text (
.txt)
- Files in the root of the directory become pages directly within the target book.
- Each first-level subdirectory becomes a chapter in the book.
- Files within a subdirectory (and its nested folders) become pages inside that chapter. Nested folders are flattened into their chapter.
- Use
--flattento ignore chapters and import all files directly into the book.
Place an optional .book-metadata.json at the root of the directory to set the book’s name and description:
{
"name": "Human Readable Book Name",
"description": "Optional description shown in BookStack"
}Precedence for the book name is: CLI --book > .book-metadata.json > directory name.
Place an optional .chapter-metadata.json file inside any subdirectory to customize the chapter’s details:
{
"name": "Human Readable Chapter Name",
"description": "Optional description shown in BookStack"
}If no metadata is present, chapter names are derived by --chapter-from:
dir(default): use the directory namereadme: use the first Markdown heading (or first non-empty line) fromREADME.md/index.mdin that folder
--max-depth <n>: Max recursion depth inside subdirectories (default: 10). Deeper nested folders are still flattened into their chapter.--chapter-from <dir|readme>: Source for chapter names when no metadata file is found.--flatten: Import everything directly into the book (no chapters).
To use this CLI, you need to:
- Enable API access in your BookStack instance
- Create an API token in your BookStack user settings
- Get the Token ID and Token Secret from BookStack
Run in development mode:
bookstack <command>Build for production:
bun run build
bun start <command>You can use a single bookstack command without bun run:
-
Option A (recommended): build a standalone binary and put it on your PATH
bun run build bun build src/bookstack-cli.ts --compile --outfile dist/bookstack sudo install -m 0755 dist/bookstack /usr/local/bin/bookstack bookstack --help
Using the provided Makefile instead:
make cli # builds dist/bookstack sudo make install # installs to /usr/local/bin/bookstack bookstack --help
-
Option B: use the bundled wrapper without installing
./bin/bookstack --help
Tip: add the repo bin to PATH for convenience in this shell:
export PATH="$PWD/bin:$PATH" bookstack --help
-
Option C: global install via Bun (may depend on Bun version)
# If you hit a lockfile parse error, remove bun.lock and retry rm -f bun.lock && bun install && bun install -g . # Then bookstack --help
-
If installed via Makefile:
sudo make uninstall # removes /usr/local/bin/bookstack -
If you manually installed the binary:
sudo rm -f /usr/local/bin/bookstack
-
If installed globally by Bun:
# Bun usually places shims under ~/.bun/bin rm -f ~/.bun/bin/bookstack
Import a documentation directory:
bookstack import ./docs --book "API Documentation" --format markdownImport a single HTML file:
bookstack import ./manual.html --book "User Manual" --format htmlTest connection and list books:
bookstack books listNote: This project has migrated from npm to Bun. Use
bun install,bun run build, andbun startfor all tasks.
Show details and contents of a book:
bookstack book show <id|name|slug>
# or if installed: bookstack book show <id|name|slug>Export a book in various formats:
# markdown (to stdout)
bookstack book export <id|name|slug> --format markdown --stdout
# html to file
bookstack book export <id|name|slug> --format html --out ./book.html
# plaintext to default filename
bookstack book export <id|name|slug> --format plaintext
# pdf to file
bookstack book export <id|name|slug> --format pdf --out ./book.pdf
Note: PDF export can take longer to generate.Show a book’s chapter/page tree:
bookstack book tree <id|name|slug>
# include IDs
bookstack book tree <id|name|slug> --ids
# only chapters or only pages
bookstack book tree <id|name|slug> --type chapter
bookstack book tree <id|name|slug> --type page
Output modes:
- `--ids` to include IDs in pretty output
- `--plain` to use simple bullets instead of tree glyphs
- `--json` to return a JSON structure of pages/chaptersExport a book's contents to a folder structure:
# write markdown files under ./<book-slug>/
bookstack book export-contents <id|name|slug> --format markdown
# choose directory and format
bookstack book export-contents <id|name|slug> --format html --dir ./out
# preview without writing
bookstack book export-contents <id|name|slug> --dry-runSearch across books/chapters/pages:
# free text
bookstack search "your query" --limit 50
# with filters (combined)
bookstack search cloud --type page,chapter --in-name intro --updated-after 2024-01-01 \
--tag docs --tag-kv topic=storage --sort-by last_commented
# json output
bookstack search cloud --type page --json
Global output flags:
- `--no-color` disable colors
- `-q, --quiet` suppress spinners and non-essential logsAvailable filters (mapped to BookStack search syntax):
--type <list>→{type:page|chapter|book}--in-name <text>→{in_name:"text"}--in-body <text>→{in_body:"text"}--created-by <slug|me>→{created_by:...}--updated-by <slug|me>→{updated_by:...}--owned-by <slug|me>→{owned_by:...}--created-after <YYYY-MM-DD>→{created_after:...}--created-before <YYYY-MM-DD>→{created_before:...}--updated-after <YYYY-MM-DD>→{updated_after:...}--updated-before <YYYY-MM-DD>→{updated_before:...}--is-restricted→{is_restricted}--is-template→{is_template}--viewed-by-me→{viewed_by_me}--not-viewed-by-me→{not_viewed_by_me}--sort-by last_commented→{sort_by:last_commented}--tag <name>→[name](repeatable)--tag-kv <name=value>→[name=value](repeatable)
List shelves:
bookstack shelves list
bookstack shelves show <id|name|slug>List images in the image gallery:
bookstack images listRead a specific image:
bookstack images read <id>Use --json for machine-readable output. The printed URL is clickable in most terminals.
Export a chapter:
# markdown to stdout
bookstack chapter export <id|name|slug> --format markdown --stdout
# html to file
bookstack chapter export <id|name|slug> --format html --out ./chapter.html
# plaintext (default filename)
bookstack chapter export <id|name|slug> --format plaintext
# pdf
bookstack chapter export <id|name|slug> --format pdf --out ./chapter.pdfPDF export warning: generation can take longer than text formats.
Export a page:
bookstack page export <id|name|slug> --format markdown --stdout
bookstack page export <id|name|slug> --format html --out ./page.html
bookstack page export <id|name|slug> --format plaintext
bookstack page export <id|name|slug> --format pdf --out ./page.pdfInspect a chapter or page and find IDs for exports/automation:
# show chapter with its pages
bookstack chapter show <id|name|slug>
# show page details
bookstack page show <id|name|slug>
# find IDs (fuzzy search)
bookstack find "intro" --type page,chapterShow a concise CLI reference:
bookstack help
# or if installed: bookstack help--no-colordisable colors-q, --quietsuppress non-essential output