# 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.

Source: https://www.jpkc.com/db/en/blog/quarkdown-cli-pdf-deployment/

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](https://www.jpkc.com/db/en/blog/quarkdown-praesentationen/) 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):

```shell
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):

```shell
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:

```shell
quarkdown c main.qd --pdf
```

Under the hood this runs via Node.js, npm and [Puppeteer](https://pptr.dev); 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:

```shell
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](https://github.com/quarkdown-labs/setup-quarkdown) — 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](https://www.jpkc.com/db/en/blog/quarkdown-praesentationen/). 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](https://quarkdown.com/wiki).

