No description
  • Rust 82.8%
  • Nix 15.8%
  • Typst 1.4%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-21 15:20:54 +01:00
envs fix(wsp): correct handling on zero paths/libraries 2026-10-21 14:54:48 +01:00
lib fix: typos, minor rewording 2026-10-21 15:20:54 +01:00
mock-pkgs/local2 fix: package spec MUST have a patch version number 2026-10-21 10:39:36 +01:00
scan-pkg add package scan tests 2026-10-21 09:29:57 +01:00
src fix: typos, minor rewording 2026-10-21 15:20:54 +01:00
tests ench: write a trailing newline into the lock 2026-10-21 10:52:33 +01:00
.gitignore first testable version 2026-10-20 01:27:06 +01:00
Cargo.lock remove dirs dep 2026-10-21 14:51:11 +01:00
Cargo.toml remove dirs dep 2026-10-21 14:51:11 +01:00
flake.lock update the modular-flake url to a public one 2026-10-21 14:51:32 +01:00
flake.nix update the modular-flake url to a public one 2026-10-21 14:51:32 +01:00
README.md fix: typos, minor rewording 2026-10-21 15:20:54 +01:00
rust-toolchain.toml workspace setup 2026-10-18 18:17:03 +01:00
rustfmt.toml workspace setup 2026-10-18 18:17:03 +01:00

typst-nix -- typst compilation in a nix derivation

Before you use this flake, please go check out Typix -- a more mature project that does basically the same thing. I am building this package, because I believe Typix to be not abstract enough, while lacking the ability to automatically resolve all the dependencies.

How to use

  1. Add to your flake inputs:
inputs.typst-nix.url = "https://git.dzuchun.ing/dzu/typst-nix.git";
  1. Run typst-lock against your typst document.

This flake exposes it at apps.<system>.default, or you may do

cargo install --git https://git.dzuchun.ing/dzu/typst-nix.git

Help text:

Statically resolve and lock `@preview` packages for a Typst project

Usage: typst-lock [OPTIONS] [ENTRYPOINT]

Arguments:
  [ENTRYPOINT]
          `.typ` file to start with, relative to `<ROOT>`

          Defaults to `main.typ`

Options:
      --root <ROOT>
          Project root

          Defaults to CWD

      --lockfile <LOCKFILE>
          Path of the lockfile to write.

          Defaults to `<ROOT>/typst.lock`

      --force
          Even if the lockfile is present at the output location, ignore it and resolve everything from scratch

      --prefetch-url-path <PREFETCH_URL_PATH>
          Path to the `nix-prefetch-url` binary

          Defaults to whatever is first in `PATH`

  -h, --help
          Print help (see a summary with '-h')

  -V, --version
          Print version

This tool produces a special file at typst.lock (or whatever you pass into --lockfile), that you can commit -- this is a direct Typst equivalent to flake.lock and Cargo.lock.

  1. Call into the nix function.

The main function is located at .lib.compileTypst. You may use aliases at .lib.<system>.compileTypst, if you don't care where pkgs come from.

Signature:

compileTypst :: {
    pkgs,
    # package to take the typst binary from
    typstPackage ? pkgs.typst,
    # possible values: pdf, png, svg, html, bundle
    format ? "pdf",
    # root of the typst project
    rootDir,
    # main typst file
    entrypoint ? "${rootDir}/main.typ",
    # lockfile, representing the dependencies
    lockfile ? "${rootDir}/typst.lock",
    # exposed in Typst as `sys.inputs`. must be an attrset of strings
    inputs ? { },
    # exposed in Typst as `sys.inputs`. must be an attrset of paths
    inputFiles ? { },
    # paths to fonts
    fontPaths ? [ ],
    # if set, Typst's own embedded fonts will be ignored
    ignoreEmbeddedFonts ? false,
    # UNIX timestamp exposed by datetime functions
    creationTimestamp ? 0,
    # pretty-format the output
    pretty ? false,
    pages ? null,
    # see typst c --help
    noPdfTags ? false,
    # see typst c --help
    ppi ? 144,
    features ? [ ],
    ...
} -> Derivation

Output of the produced derivation is your PDF or HTML respectively.

Known limitations

  • First version only supports packages from typst universe. There is a code in place to support custom (incl. local) repositories, but this is deferred.
  • Tool operates on the "fail open" strategy: non-existent or unresolvable packages are skipped with a warning, while errors in your entrypoint are fatal.
  • If the package traversal fails in any way, it will remain in the manifest, but without its dependencies. You will also see an explicit message about this hard failure.
  • Tool only understands imports and includes with literal string sources. This may or may not be relaxed to "pure+local eval values" in the future.
  • All the resolutions and downloads are naive and never retried. If one of the packages you are sure to exist fails, please rerun.
  • Power loss durability is not a goal. If you think that the lockfile is corrupted, just regenerate it.