Typst #import vs #include
#include for inserting content. #import for sharing functions and variables. Plus the @preview/ namespace for community packages.
The decision
| Want | Use |
|---|---|
| Insert file content into document | #include |
| Use functions defined elsewhere | #import |
| Use community package | #import "@preview/..." |
| Personal utility library | #import "@local/..." |
#include — for body content
// main.typ
#set page(margin: 1in)
#set text(font: "New Computer Modern", size: 11pt)
#include "frontmatter/title.typ"
#include "frontmatter/abstract.typ"
#include "chapters/01-introduction.typ"
#include "chapters/02-methods.typ"
#include "chapters/03-results.typ"
#bibliography("references.bib")#import — for code sharing
// helpers.typ
#let highlight-block(content) = block(
fill: rgb("#fff8c5"),
inset: 8pt,
radius: 4pt,
content,
)
#let warning(content) = block(
fill: rgb("#fee"),
stroke: 1pt + red,
inset: 8pt,
[⚠️ #content],
)
// main.typ
#import "helpers.typ": highlight-block, warning
#highlight-block[Important note here]
#warning[This is dangerous]Community packages from @preview
// CeTZ for diagrams (TikZ alternative)
#import "@preview/cetz:0.2.0": canvas, draw
#canvas({
draw.line((0,0), (2,2))
draw.circle((1,1), radius: 0.5)
})
// tablex for advanced tables
#import "@preview/tablex:0.0.8": tablex, cellx
#tablex(
columns: 3,
cellx(fill: yellow)[Header A],
[Header B], [Header C],
[data], [data], [data],
)
// CV template
#import "@preview/modern-cv:0.2.0": *
#show: cv.with(
author: "Your Name",
email: "you@example.com",
)Local packages (@local)
// Create at:
// Linux/Mac: ~/.local/share/typst/packages/local/my-utils/0.1.0/
// Windows: %APPDATA%\typst\packages\local\my-utils\0.1.0\
// my-utils/0.1.0/typst.toml
[package]
name = "my-utils"
version = "0.1.0"
entrypoint = "lib.typ"
authors = ["You"]
// my-utils/0.1.0/lib.typ
#let mybox(body) = block(stroke: 1pt, inset: 4pt, body)
// In any of your projects:
#import "@local/my-utils:0.1.0": mybox
#mybox[my custom box]Common mistakes
- Using
#includefor code sharing. Inserts content; functions defined inline don't propagate to outer scope. Use#import. - Missing version in
@preview. Always pin:@preview/cetz:0.2.0, not@preview/cetz. - Forgetting
: *for full import.#import "file.typ"imports as namespace; you access functions asfile.foo. Use: *to bring everything into local scope. - Circular includes. File A includes B which includes A — Typst detects and errors. Restructure.
TypeTeX auto-fetches @preview packages — drop in an #import statement and the package is available immediately. No install or path setup.
Frequently Asked Questions
#include "file.typ" inserts the file's content at that point — like LaTeX's \input. #import "file.typ": ... brings specific names (functions, variables) from that file into scope without inserting content. Use #include for chapter content; use #import for sharing reusable functions and styles.
Create a main.typ with #include statements for each chapter: #include "chapters/01-intro.typ". The file's content (text, headings, etc.) appears at that point in the main document. Each chapter is its own .typ file with normal Typst markup. No setup or registration needed.
In one file: #let highlight(text) = block(fill: yellow, inset: 4pt, text). Then in another: #import "helpers.typ": highlight. Now #highlight[stuff] works. To import everything: #import "helpers.typ": *. Use this for shared styles, custom commands, theorem environments.
#import "@preview/package-name:0.1.0": *. The @preview namespace is the official Typst package registry (typst.app/universe). Specify the version. Common packages: cetz (drawing), tablex (advanced tables), modern-cv (CV templates), unify (units).
Local packages stored on your machine. Place a folder at ~/.local/share/typst/packages/local/my-pkg/0.1.0/ (or equivalent on Windows/Mac). Then #import "@local/my-pkg:0.1.0": *. Useful for custom utility libraries shared across multiple Typst projects you author.
It works but isn't ideal — #include inserts content as text, so a function defined in the included file becomes inline code at the include point. Better: define functions in shared file, then #import them. #include is for body content; #import is for reusable code.
#import "helpers.typ": foo, bar — imports only foo and bar. #import "helpers.typ" — imports the file as a module and you access via prefix: helpers.foo(...). #import "helpers.typ": * — imports everything (use cautiously to avoid name collisions).
Yes. Create a typst.toml manifest with name, version, entrypoint. Place in @local namespace for personal use. To publish to @preview, submit a PR to github.com/typst/packages — community-curated registry. Most projects don't need a full package; just shared .typ files imported locally is enough.
Typst is much simpler. LaTeX has \usepackage and complex package metadata; Typst has #import with version pinning built in. LaTeX packages must be installed in TeX Live/MiKTeX globally; Typst packages from @preview are auto-fetched on first use. No 'install Pygments' or 'enable shell-escape' edge cases.