README.md

March 27, 2026 · View on GitHub

typos logo

typos

A note-taking system built on Typst instead of Markdown.


Recent changes (v0.2.5)

  • Wayland fix — resolved EGL crash in AppImage on Wayland compositors (#1)

v0.2.4

  • Dark mode — warm "parchment at night" theme with syntax-aware editor colors, toggle in toolbar
  • Welcome screen — onboarding GUI for opening or creating vaults without CLI
  • Cross-platform builds — macOS (ARM + Intel), Linux (.deb, .AppImage), Windows (.exe)
  • Compilation timeout — 10s timeout prevents infinite loops from freezing the app
  • Backlinks dedup — duplicate backlinks from multiple references to the same note are removed

v0.2.3

  • Tinymist LSP — integrated Typst language server for autocompletion of built-in functions and parameters
  • Editor improvements — Tab/Shift-Tab indentation (2 spaces), auto-close brackets, smart Enter indent, toggle comments (Cmd+/)

v0.2.2

  • PDF preview — toggle between HTML and pixel-perfect PDF preview (via pdf.js); supports clickable note links
  • xlink-scope — cross-link two notes from a third (e.g. journal → task → project) with inline property display
  • get-prop — read any note's property from vault index in Typst
  • Optional properties in PDF export — choose whether to include metadata when sharing as PDF

Notes are plain .typ files with built-in support for typed metadata, cross-references, backlinks, and knowledge graphs — all powered by Typst's own type system.

Instead of reinventing frontmatter parsers, Dataview-style query languages, and custom renderers, typos lets Typst do what it already does: functions, types, and content transformations. The tooling layer (Rust) handles AST extraction and indexing, while the Typst framework handles rendering.

Editor with live preview
Editor with Typst syntax highlighting and live HTML preview

Programmable vault.typ
Programmable type system — define your note types in vault.typ

Knowledge graph
Interactive knowledge graph visualization

Architecture

typos/
├── notes-app/          Tauri desktop app (Svelte + CodeMirror)
├── notes-core/         Rust library (AST parsing, indexing, compilation)
├── notes-cli/          CLI binary wrapping notes-core
└── notes-framework/    @local/notes Typst package

Data flow:

  1. You write .typ notes with typed constructors and cross-references
  2. The indexer parses all files via typst-syntax AST and builds notes-index.json
  3. When Typst compiles a note, the framework reads the index to resolve links and render backlinks

Desktop App

A native desktop app built with Tauri 2, Svelte 5, and CodeMirror 6. Editor with Typst syntax highlighting, live HTML preview, full-text search, and note management. Typst compiler and framework are bundled — no external dependencies needed for end users.

Download

PlatformDownload
macOS (Apple Silicon)typos_0.2.4_aarch64.dmg
macOS (Intel)typos_0.2.4_x64.dmg
Linux (Debian/Ubuntu)typos_0.2.4_amd64.deb
Linux (AppImage)typos_0.2.4_amd64.AppImage
Windowstypos_0.2.4_x64-setup.exe

macOS note: The app is not yet code-signed. On first launch macOS may show "app is damaged" or "unidentified developer". To fix, run in Terminal:

xattr -d com.apple.quarantine /Applications/typos.app

Or: System Settings → Privacy & Security → scroll down → click "Open Anyway".

Prerequisites (building from source)

Place both binaries in notes-app/src-tauri/binaries/:

notes-app/src-tauri/binaries/
├── typst-aarch64-apple-darwin        # macOS ARM
├── typst-x86_64-apple-darwin         # macOS Intel
├── typst-x86_64-unknown-linux-gnu    # Linux
├── typst-x86_64-pc-windows-msvc.exe  # Windows
├── tinymist-aarch64-apple-darwin     # macOS ARM
├── tinymist-x86_64-apple-darwin      # macOS Intel
├── tinymist-x86_64-unknown-linux-gnu # Linux
└── tinymist-x86_64-pc-windows-msvc.exe # Windows

You only need the binaries for your current platform. The notes framework is bundled automatically from notes-framework/.

Development

cd notes-app
npm install
npx tauri dev

Production build

cd notes-app
npx tauri build

The compiled app bundle will be in notes-app/src-tauri/target/release/bundle/.

Keyboard shortcuts

ShortcutAction
Cmd+SSave current note
Cmd+KSearch notes
Cmd+OOpen vault
Cmd+NNew note

CLI

Installation

# Requires Rust toolchain
cargo install --path notes-cli

# Install the Typst framework as a local package
# macOS:
cp -r notes-framework/src/ ~/Library/Application\ Support/typst/packages/local/notes/0.1.0/src/
cp notes-framework/typst.toml ~/Library/Application\ Support/typst/packages/local/notes/0.1.0/
# Linux:
cp -r notes-framework/src/ ~/.local/share/typst/packages/local/notes/0.1.0/src/
cp notes-framework/typst.toml ~/.local/share/typst/packages/local/notes/0.1.0/

Create a vault

notes init my-vault
cd my-vault

This generates:

  • vault.typ — vault configuration with note type definitions
  • note-paths.csv — registry of all note files
  • notes-index.json — metadata index
  • notes/welcome.typ — your first note

Create notes

notes new "Build MVP" --type task
notes new "programming/rust" --type note
notes new "programming/rust/closures" --type note

The path syntax (/) creates a hierarchy. Parent notes are auto-created if they don't exist:

notes/build-mvp.typ                   → id: "build-mvp"
notes/programming--rust.typ           → id: "programming/rust"
notes/programming--rust--closures.typ → id: "programming/rust/closures"

Other commands

notes index                          # rebuild index
notes list                           # list all notes
notes list --type task               # filter by type
notes search "rust"                  # full-text search
notes backlinks "programming/rust"   # show incoming links
notes graph                          # knowledge graph
notes compile programming/rust       # compile to HTML
notes compile programming/rust --format pdf
notes watch welcome                  # live recompilation
notes rename old-id new-id           # rename with reference updates
notes delete note-id                 # delete note
notes sync                           # sync after external changes (e.g. git pull)

Writing Notes

A note is a regular .typ file. The title heading is rendered automatically:

#import "../vault.typ": *

#show: card.with(
  title: "closures",
  tags: ("rust", "fp", "@programming/python"),
  difficulty: "hard",
)

Closures capture variables from their environment.
See also #xlink("programming/rust/traits").

#show: type.with(title: "...") — registers the note with typed metadata. The id and parent are derived from the filename automatically.

Cross-references

  • In properties"@id" string: tags: ("rust", "@programming/python"). Rendered as a clickable link, indexed automatically.
  • In body text#xlink("id"): See #xlink("programming/rust"). Rendered as an inline link.

Both appear in backlinks of the target note. Backlinks are rendered automatically at the bottom of each note.

Framework

The Typst framework (@local/notes) provides:

ModulePurpose
vault.typnew-vault() — initializes vault object from index data
note-type.typCreates typed constructors for #show: rules
xlink.typCross-reference resolution via index lookup
backlinks.typRenders incoming links at the end of each note
graph.typText-based graph + DOT output for Graphviz
index.typIndex reading and query helpers

The user's vault.typ ties it together:

#import "@local/notes:0.1.0": new-vault, as-branch

#let vault = new-vault(
  index: json("notes-index.json"),
)

#let tag  = (vault.note-type)("tag")
#let note = (vault.note-type)("note", fields: (tags: (), links: ()))
#let task = (vault.note-type)("task", fields: (tags: (), priority: ""))
#let xlink = vault.xlink

Roadmap

  • Tauri app — desktop GUI with editor, preview, search
  • Compile & watchnotes compile and notes watch via typst subprocess
  • Type validation — CLI validates --type against vault.typ definitions
  • Note renamenotes rename with automatic reference updates
  • Typst bundling — typst binary as Tauri sidecar, framework as bundled resources
  • Autocomplete — note ID suggestions for @ references and #xlink()
  • Vim mode — toggleable vim keybindings with :w, :q, :wq
  • Journal — daily journal entries with automatic date and previous-entry linking
  • Knowledge graph — interactive graph visualization with vis-network
  • Design system — warm parchment palette, Greek iconography, custom app icon
  • xlink-scope — cross-link notes with inline property display
  • PDF preview — pixel-perfect PDF preview with clickable links (pdf.js)
  • Tinymist LSP — Typst language server for autocompletion of built-in functions
  • Dark mode — warm "parchment at night" theme (UI + editor + preview)
  • Cross-platform — macOS (ARM + Intel), Linux, Windows via GitHub Actions CI
  • Topos — rename vault to topos (τόπος) :)
  • Programmatic compilation — replace subprocess with typst Rust crate (World trait)
  • Incremental indexing — skip unchanged files based on mtime
  • iOS support — via Tauri v2 mobile

Acknowledgements

  • basalt — Typst Zettelkasten framework that inspired the vault, xlink, and backlinks architecture (GPL-3.0)
  • Typst — typesetting engine used for rendering and compilation (Apache-2.0)
  • Tauri — desktop application framework (MIT or Apache-2.0)
  • Tinymist — Typst language server for autocompletion (Apache-2.0)
  • CodeMirror — code editor component (MIT)
  • pdf.js — PDF rendering in preview (Apache-2.0)
  • vis-network — knowledge graph visualization (Apache-2.0)