@uniweb/unipress
v0.4.32
Published
Compile a content directory into a document (PDF, EPUB, Paged.js HTML, Typst source bundle, DOCX, XLSX) using a Uniweb foundation. Five built-in templates: book, monograph, report, data-report, directory.
Readme
unipress
Compile a directory of markdown into a document — typeset PDF, EPUB, Word, Excel, Paged.js HTML, Typst source — using a foundation that knows the conventions of the kind of document you're writing.
You already write in markdown, and you keep it organized — a folder of files, numbered for order, maybe a README and some assets. That's good structure. But turning it into one polished, shareable document usually means pandoc incantations, a LaTeX toolchain, or a pile of glue scripts.
unipress does it in one command.
Quick start: markdown you already have → a PDF
Point it at your folder:
cd my-docs # a folder of .md files
unipress compile .There's no project to set up. The first time, unipress sees there's no config, offers to create a small document.yml for you, and produces the PDF — a clean, single-column article: A4, typeset prose, an inline title block, no chapters. Numbered filenames (01-intro.md, 02-overview.md) set the section order; README.md and draft files (_notes.md) are left out.
Prefer no prompts? --yes takes the defaults — the A4 article, PDF output:
unipress compile . --yes
unipress compile . --yes --format epub # or any format the foundation emitsThe generated document.yml is yours to keep and edit — it holds the title, reading order, and output format. Re-run compile whenever the content changes.
A4 or US Letter?
The default page size is A4. In the US and Canada you'll want Letter — open the generated document.yml and change book.trim from a4 to letter:
book:
kind: article
trim: letter # 8.5 × 11 in (was: a4)Then re-run unipress compile .. A couple of other one-line tweaks live in the same book: block — numbered sections (structure: { numberHeadings: true }) and a table of contents (structure: { toc: true }). See the article guide for the full list.
Starting from scratch
No content yet? Scaffold a starter from a template:
unipress create my-book --template book --title "My Book" --author "Your Name"
cd my-book && unipress compile .create writes a content-only directory — markdown, a document.yml, optional theme.yml and assets/; no package.json, no node_modules. Pick the template that matches your document (see Pick a template) — it carries the typography and structure so a book reads like a book and a directory like a directory.
Planning to publish? There's a full author's guide that takes a book from your folder all the way to Amazon and print — Publishing your book.
What it makes
| Format | What it's for |
|---|---|
| PDF | The finished, typeset document. Real typography, real pagination, ready to print or share. Built on Typst, the modern typesetting system. |
| EPUB | The format Kindles and other ebook readers use. |
| Word (.docx) | When a journal, committee, or collaborator needs a Word file. |
| Excel (.xlsx) | When the document is structured data — a directory, a dataset, a registry — rather than prose. |
| Paged.js HTML | Browser-paginated HTML you can print to PDF or post on the web. |
| Typst source | The .typ files unipress feeds the compiler. Useful if you want to take the typesetting further yourself, or hand off to a designer. |
Equations work in the standard LaTeX style — $E = mc^2$ for inline, $$...$$ for displayed. Tables, lists, footnotes, code blocks, and images all behave the way you'd expect from markdown.
Publishing your book
Making the files is half the job; getting your book onto Amazon, Apple Books, and print-on-demand is the other half. The Publishing your book guide is an end-to-end walkthrough written for authors — the proof → final workflow, covers and images, trim sizes, EPUB validation, print-on-demand, ISBNs, and metadata — with links to every store and service.
Two ways to use it
For authors. unipress is a tool. Pick a template, write markdown, compile. The template knows the conventions for its kind of document — typography, structure, the bits that make a book look like a book and a directory look like a directory. You handle the content; the template handles everything else.
For developers. unipress is an engine. A foundation you write declares what section types exist (type: Chapter, type: Bibliography), where their data comes from (markdown content, file-based or API-backed collections, Loom expressions templating against hierarchical data), and what output formats it can emit (outputs: { docx, xlsx, pdf, custom-format }). Authors mix prose with structured records and computed values in the same document; unipress runs your foundation against their content and produces whatever your foundation declares — typeset book, accessible EPUB, regulatory report, structured data feed. The same foundation can also drive a Uniweb website, so the work is never single-purpose.
Foundations consume @uniweb/press for the bytes-emitting work. Press is the output layer (Word, Excel, Typst today; more formats shipping); the foundation is your vocabulary.
→ For the deeper pitch — mixed prose-and-data, Loom templating, custom output adapters — see docs/for-developers.md.
Install
Homebrew (macOS and Linux — recommended). No Node, no manual download:
brew install uniweb/unipress/unipressUpdates land via brew upgrade unipress. On recent Homebrew (6.x), the first install or upgrade may refuse the tap until you trust it once — run brew trust uniweb/unipress, then re-run the command. The macOS binary is signed with the Proximify Inc. Developer ID and Apple-notarized — no Gatekeeper warnings.
Manual download (Windows, or any platform without Homebrew). Grab the asset for your platform from the releases page, make it executable (Unix), and put it somewhere on your PATH. On macOS and Linux, /usr/local/bin/unipress is a common location.
npm. If you already have Node ≥ 20.19:
npm i -g @uniweb/unipressPick a template
Built-in templates ship with the binary. Run unipress list-templates for the picker.
| Template | Foundation | Outputs | Use case |
|---|---|---|---|
| article | @uniweb/book | pdf, typst, pagedjs, epub | Single-column paper (A4/Letter, no chapters) — the default for a loose folder of markdown |
| book | @uniweb/book | pdf, typst, pagedjs, epub | Trade book, long-form prose with chapters |
| monograph | @uniweb/book | pdf, typst, pagedjs, epub | Scholarly monograph (royal-octavo, classical typography) |
| report | @uniweb/book | pdf, typst, pagedjs, epub | Technical report (trade-7x10, block paragraphs) |
| data-report | @uniweb/data | xlsx, docx | Aggregate metrics across structured records |
| directory | @uniweb/data | xlsx, docx | Flat records listing with a filterable surface |
article and book/monograph/report are one foundation, two genres: article is single-column and chapter-less (LaTeX's article), the others are chaptered with a title page and TOC. Switch by setting book.kind.
Per-template guides: docs/templates/.
More templates land as more foundations ship — cv, resume, thesis are on the roadmap for upcoming releases.
Custom foundations
Any foundation that declares an outputs: { … } map on its default export can drive unipress. Point document.yml's foundation: at:
- a registry ref:
@<namespace>/<name>@<version>— fetched from the Uniweb registry, cached locally, - a URL:
https://…/entry.js, - a local filesystem path:
./foundation,/abs/path, etc.
The local-path form is the everyday dev loop — point unipress at a foundation directory you're iterating on, no publish step needed:
unipress compile my-doc --foundation ../my-foundationFor the foundation contract — the outputs: map, the getOptions(website, hostHints) function, what bytes a foundation can emit — see the foundation authors' guide. Foundations are distributed via the Uniweb registry, not npm.
Below this point is reference material — useful when you want to do something beyond the basics, or when something doesn't behave as expected.
CLI reference
unipress compile <dir> [options]
--format <fmt> Output format (pdf | typst | docx | xlsx | pagedjs | epub).
Overrides the format: field in document.yml.
--foundation <ref> Override document.yml's foundation. Accepts:
- registry ref: @<namespace>/<name>@<version>
- URL: https://…/entry.js
- path: ./foundation, /abs/path, …
--out <path> Output file (default: ./<dir-basename>.<ext>).
--variant <name> Build an alternate top-level config <name>.yml inside <dir>
(e.g. --variant document-book → document-book.yml) instead of the
default document.yml. Lets one manuscript hold several cuts —
an A4 article and a trade book — side by side. The name is used
as given (a .yml extension is assumed if omitted).
--config <path> Explicit config file (default: <dir>/unipress.config.js).
--typst-binary <p> Path to a typst binary (skips the managed download).
--keep-temp On typst-compile failure, keep the temp dir for inspection.
--yes If no document.yml exists, generate one from the folder's
markdown without prompting (book foundation by default;
honors --foundation/--format).
--verbose Per-step progress to stderr + stack traces on errors.
unipress create <dir> [options]
--template <id> Template to scaffold (interactive picker if omitted).
Run `unipress list-templates` to see available ids.
--title <str> Document title (prompts if omitted).
--author <str> Document author (prompts if omitted).
--force Overwrite non-empty <dir>.
--yes Skip prompts (requires --template).
unipress list-templates
List the templates available, one per line, with description, outputs,
the foundation each pins, and the source URL where the foundation lives.
unipress inspect <dir> [options]
Dump the parsed content as JSON (debugging aid).
--full Include web-only fields (assets, icons, etc.).
--summary Replace pages[] with route strings only.
--page <route> Keep only the page matching <route>.
--depth <n> Truncate nested values beyond depth n.
--foundation <ref> Override document.yml's foundation.
--no-orchestrate Skip running the foundation; show only the parsed content.
unipress --help
unipress --versionExit codes: 0 success, 1 user-addressable error, 2 internal error (re-run with --verbose for a stack trace).
Configuration
document.yml
The content-directory-level config. Fields unipress reads:
| Field | Purpose |
|---|---|
| name | Document name (used as a title fallback). |
| foundation | Registry ref (@ns/name@ver), URL, or local path to the foundation. |
| format | Default output format. Overridable by CLI --format or unipress.config.js. |
| content: | Reading order — chapter names with any numeric prefix stripped (00-intro.md → intro). pages: is accepted as an alias. |
| paths: | Content-directory overrides. paths: { pages: . } reads markdown loose at the project root instead of a content/ subfolder. |
| book:, report:, collections: … | Foundation-specific config blocks. The foundation's getOptions reads these. |
site.yml is also accepted as a fallback for compatibility with existing Uniweb site directories.
Several cuts of one manuscript
Keep more than one top-level config beside your content and pick one per build with
--variant. The same chapters can ship as an A4 article and a trade book:
my-book/
document.yml # A4 article (the default: unipress compile .)
document-book.yml # trade 6×9 with covers
assets/front.png
01-intro.md 02-…
unipress compile . # → article (document.yml)
unipress compile . --variant document-book # → book (document-book.yml)--variant <name> reads <name>.yml from the content directory — the name is used as
given (no prefixing) with .yml assumed when omitted. Config-declared assets —
book.covers.front, banners, logos — are resolved from the config the build reads, so
covers must live in the config unipress reads (the --variant file or the default
document.yml), not in a unipress.config.js --config override, whose asset paths
aren't scanned.
unipress.config.js
Optional ESM file for things awkward in YAML — imports, computed values, format-specific overrides. Auto-discovered at <dir>/unipress.config.js or explicit via --config <path>.
import { defineUnipressConfig } from '@uniweb/unipress'
export default defineUnipressConfig({
out: './dist/my-book.pdf', // overrides --out default
format: 'pdf', // overrides document.yml format
typst: {
version: '0.14.2', // override the pinned Typst version
binary: '/usr/local/bin/typst', // skip the managed download
},
})Plain export default { … } works equally well; defineUnipressConfig is an identity wrapper for editor autocomplete.
Relative paths in the config (out, foundation, typst.binary) resolve against the config file's directory — matching Vite / Astro convention.
Precedence chain
CLI flags > unipress.config.js > document.yml > defaultsApplied per-field.
Typst binary
--format pdf requires a Typst binary. unipress pins 0.14.2 and manages the download:
- Cache location:
$UNIPRESS_CACHE_DIR>$XDG_CACHE_HOME/unipress>~/Library/Caches/unipress(macOS) >~/.cache/unipress(fallback). Binary path:<cache>/typst/<version>/typst. - Override: pass
--typst-binary <path>or settypst.binaryinunipress.config.js. - Checksum verified: each download is SHA-256-checked against the digest pinned in
src/typst/versions.js.
Where things stand
unipress is pre-1.0. The CLI is stable enough to write real documents with — the book template, in particular, is well-tested. Future versions may change small things, but document.yml files and project folders from today should keep working: scaffolded projects pin a specific foundation version, and registry artifacts are immutable.
Foundations are fetched on first use. The bundled templates pin foundations served from https://uniweb.github.io/unipress/foundations/…; the first compile downloads and caches the one your document.yml names (alongside the Typst binary). To iterate on a foundation locally, pass --foundation <path> pointing at a built foundation directory; to point at a different registry, set UNIWEB_REGISTRY_URL.
Documentation
- Publishing your book — the end-to-end guide for authors: the proof → final workflow, covers and images, trim sizes, EPUB, print-on-demand, ISBNs, and metadata.
- Template guides — conventions and settings per document kind: article, book, monograph, report, data-report, directory.
- Troubleshooting — common errors and fixes; every named error class maps to a cause and a concrete next step.
- For developers — building a foundation: section types, data sources, and custom output formats.
See also
- @uniweb/press — the output layer foundations consume to produce Word/Excel/Typst/EPUB. Foundation authors interact with it directly.
- @uniweb/build — the framework's content-collection pipeline. unipress consumes the sharp-free
/contententry. - Uniweb — the larger framework. Foundations originate here; unipress brings them to the command line.
License
Apache-2.0 — see LICENSE.
