Creating templates

A Craftadoc template is an ordinary Typst project with two extra files: craftadoc.json, which describes the form, and example.json, which holds sample values. This page builds a small letter template from scratch; the template format has the full reference.

1. The folder

letter/
├── craftadoc.json   the form and the template's details
├── example.json     sample values
├── main.typ         the Typst document
└── assets/          images, if any

2. Describe the form

craftadoc.json lists the template's details and its inputs as JSON Schema. Every field has a title (its label) and limits such as maxLength.

{
  "format": "craftadoc-template/0",
  "name": "Simple letter",
  "description": "A one-page letter with sender, recipient and body.",
  "entry": "main.typ",
  "language": "en",
  "categories": ["letter"],
  "license": { "spdx": "MIT", "authors": ["Your name"] },
  "inputs": {
    "type": "object",
    "additionalProperties": false,
    "required": ["sender", "recipient", "subject", "body"],
    "properties": {
      "sender": { "type": "string", "title": "Your name", "maxLength": 60 },
      "recipient": { "type": "string", "title": "Recipient", "maxLength": 60 },
      "subject": { "type": "string", "title": "Subject", "maxLength": 100 },
      "body": { "type": "string", "title": "Letter", "maxLength": 4000, "x-craftadoc": { "kind": "markdown" } }
    }
  }
}

3. Sample values

example.json contains a complete, valid set of values. Craftadoc uses it for the template's thumbnail, as the starting point of new documents, and when you compile the template on your own computer.

{
  "sender": "Jane Doe",
  "recipient": "John Smith",
  "subject": "Thank you",
  "body": "Dear John,\n\nThank you for your kind help.\n\nBest regards"
}

4. The Typst document

Import the Craftadoc helper package and read the values. Values are always data: a name like #strong[x] is printed exactly as typed, never run as code.

#import "@craftadoc/form:0.1.0": values, rich

#let d = values(json("example.json"))

#set page(paper: "a4", margin: 2.5cm)
#set text(font: "Lato", size: 11pt)

#d.sender
#v(1cm)
To: #d.recipient

*#d.subject*

#rich(d.body)

See the Typst helper package for rich, icon, filled and date.

5. Try it on your computer

Install the Typst CLI and download the helper package and fonts. Then compile with the same fonts Craftadoc uses:

typst compile --ignore-system-fonts --font-path fonts --package-path packages main.typ

Your template compiles exactly like any Typst document, using the values from example.json.

Fonts

Templates can use these fonts without shipping them: Fira Sans, Hind Madurai, Lato, Roboto Slab, Font Awesome 7 (through the icon helper), and Typst's built-in Libertinus Serif, New Computer Modern and DejaVu Sans Mono.

To use another font, put its .ttf or .otf files anywhere in the template folder, for example assets/fonts/, together with its licence file. Craftadoc loads them for your template only, and you use them by family name as usual: #set text(font: "Inter"). Fonts count towards a template's size (at most 10 MB in total, 5 MB per file), and you need the right to redistribute them (fonts under the SIL Open Font License are a safe choice). To try it locally, add the template folder as a font path:

typst compile --ignore-system-fonts --font-path fonts --font-path . --package-path packages main.typ

6. Publish

Sign in and open Publish a template. You can either:

  • upload the template folder as a .zip file, or
  • import from GitHub: enter a public repository and a tag or branch.

Craftadoc checks the template (form, sample values, a test compile) before publishing it. Choose whether it's open (listed in the catalogue) or private (only you can use it). Publishing again creates a new version; existing documents keep using the version they were made with. On the template's page you decide whether signed-in people may download its source (the Typst files); it's off until you share it. Sharing the source also lets people make a copy to change, if your licence allows changes: they're credited as based on your template, and open copies are listed on its page.

Rules

  • Never pass input to eval, and don't use Markdown packages that run raw Typst; use rich instead.
  • Keep everything inside the template folder; Craftadoc compiles without network access.
  • Only publish templates you have the right to share, with their licence and authors filled in.