Quarkdown in Practice: CLI, PDF Export & Deployment

Part 8 of the Quarkdown series: the key CLI options, PDF export with Puppeteer, the permission system (secure by default), live preview and deployment via CI/CD.

by ·

For seven parts it was about content. Now it's about the tool: how do you get from .qd source to a finished artifact — and onto the web? The presentation from part 7 was the last format; this part is the practical underpinning you need for every format.

A local CLI tool

For context up front, because it shapes the whole chapter: Quarkdown runs mostly through the command line. It's not an online service or a server-side editor, but a locally installed tool. The actual engine is a JVM library (written in Kotlin); the CLI quarkdown-cli is the main interface to it and drives the entire pipeline process. Besides compiling (quarkdown c) there's the project wizard (quarkdown create), the web server (quarkdown start), an interactive REPL (quarkdown repl) and diagnostics (quarkdown doctor).

You don't have to live in the terminal for this: an official VS Code extension and a language server (quarkdown-lsp) offer a preview button, syntax help and more — they wrap the CLI but drive the same compiler under the hood. In CI/CD it's simply the same CLI call in a workflow. So everything in this part revolves around exactly this one tool.

Compiling

The heart of it is quarkdown c. With multiple source files you point at the root file (the one that includes the others):

quarkdown c main.qd

The most important options:

  • -o <dir> / --out — output directory (default ./quarkdown-output), --out-name for the file name.
  • -r <renderer> — target: html (default), html-pdf or text (plain text).
  • --strict — aborts on errors instead of rendering them as boxes into the document. Indispensable for CI builds.
  • --clean — empties the output directory first (destructive).
  • --pipe — writes to stdout instead of a file, ideal for piping to other commands.
  • --timeout <s> — maximum duration (default 30 s, 0 disables it).

Live preview

For working on the text you combine -p (preview, opens the browser and reloads) with -w (watch, recompiles on every change):

quarkdown c main.qd -p -w

The browser you pick via -b (chrome, firefox, edge, none, a path …), the port via --server-port. Worth knowing: for paged documents a running web server is mandatory (a paged.js requirement) — -p starts it automatically, alternatively quarkdown start -f <file> works.

PDF export

--pdf produces a PDF file that matches pixel-for-pixel what Chrome would render from the HTML — all document types and features included:

quarkdown c main.qd --pdf

Under the hood this runs via Node.js, npm and Puppeteer; package managers and install scripts set up these dependencies for you. On some Linux distributions without a headless sandbox, --pdf-no-sandbox helps (use with care). This is why PDF export is a bit slower than plain HTML compilation — it starts a real browser in the background.

Secure by default: the permission system

A detail that sets Quarkdown apart from many scripting-capable tools: it is secure by default. Because .qd documents can execute code, compilation runs in a restrictive sandbox. By default only project-read (reading in the project folder) and native-content are allowed. Everything else you must grant explicitly:

quarkdown c main.qd --allow network --allow global-read

The permissions are project-read, global-read, network, native-content, process and all. So if you compile someone else's .qd files, you don't risk them quietly touching the network or file system — a well-thought-out security approach.

Diagnosis with the doctor

quarkdown doctor reports on the installation. doctor env checks the external runtimes (JVM, Node.js, Puppeteer), doctor get install-dir returns the install path (handy in shell scripts), and doctor get agent-skill shows the path to the bundled AI agent skill — more on that in the next part.

Deployment

Because the HTML build is static, you can put the output directory on any web space, a CDN or GitHub Pages — no server code needed. Static extra files (such as robots.txt or CNAME) you place in a public/ folder next to the main file; Quarkdown copies it into the output unchanged. For automation there's a ready-made GitHub action — a CD workflow takes under three minutes according to the project. Equally, the build can be uploaded into an Apache subfolder; the principle "one folder of static HTML" stays the same.

FAQ

Where does Quarkdown write the output?

By default to ./quarkdown-output. Via -o you set your own directory — sensible for keeping build artifacts out of the source folder. --clean tidies up first, but is destructive.

Do I also need Node.js for plain HTML?

No. Node.js, npm and Puppeteer are only needed for PDF export. HTML compilation runs on the JVM alone. If you never produce PDFs, you can ignore these dependencies.

How do I build Quarkdown in CI?

With the setup-quarkdown action, then quarkdown c main.qd --strict (so the build goes red on errors) and a deploy step that publishes the output directory. --strict is crucial here, otherwise errors render silently as boxes into the document.

Further reading

The last content stop was part 7: Presentations. Next comes the part that brought this series onto this blog in the first place: Quarkdown & AI — the bundled agent skill and why Markdown-native work fits this platform's concept. The full list of options is in the official wiki.