Cerbo (/ˈt͡serbo/) is Esperanto for "brain". It is a local-first markdown wiki editor that treats the filesystem as a
first-class citizen. It stores all knowledge as plain files you fully own, with
cerbo:// link-based graph navigation as the core interaction model.
- Local-First & Private: Your data stays on your machine in plain Markdown files and folders. No cloud dependency, no proprietary formats.
- Desktop & CLI: Work your way. Use the GUI for visual editing or the
cerboCLI for terminal workflows, automation, and headless indexing. - UUID-Based Storage: Each page/object is a
.cerbo/objects/<uuid>/folder, with no slug derivation or name-based paths. - Wikilink-Free: Uses
cerbo://<uuid>links instead of[[Wikilinks]]. - Backlinks & Annotations: Automatic backlink tracking (
backrefs.ttl) and HackMD-style annotations ([Text]{prefix:Type}→annotations.ttl). - Multiple Vaults: Manage multiple isolated knowledge bases (vaults) anywhere on your disk.
- XDG Compliant: App configuration and caches follow the XDG Base Directory Specification.
- Backend: Rust Workspace (Core library + CLI + Tauri Desktop)
- Frontend: Svelte 5 + Carta (Markdown Editor) + Tailwind CSS
- Package Manager: Bun
- Environment: Nix Flakes
This project uses Nix Flakes to manage the development environment, including Rust, Bun, and build dependencies.
You can enter the development shell using:
nix developAlternatively, if you have direnv installed, just run direnv allow and the environment will be automatically loaded when you enter the directory.
All development commands (bun, cargo) should be run inside the Nix development shell:
bun run tauri dev # Start Tauri app with hot reload
cargo check # Run Rust workspace type checks
cargo test -p cerbo-core # Run core logic tests (use --test-threads=1 for isolation)Use nix build to build the components:
nix build .#cerbo-desktop # Build Desktop App
nix build .#cerbo # Build CLI Binary- Configuration:
$XDG_CONFIG_HOME/cerbo/vaults.json(defaults to~/.config/cerbo/). Stores only vault names and paths. - Cache:
$XDG_CACHE_HOME/cerbo/(defaults to~/.cache/cerbo/). Stores the link index and derived data. - Vaults: Each vault has a
.cerbo/directory containing:objects/<uuid>/- UUID-based object storage (type: Product, Source, Attachment, Ontology)index.json- Maps titles to UUIDs and vice versaontology-map.json- Maps prefixes (e.g., "schema") to ontology UUIDs
Cerbo uses cerbo://<uuid> links instead of wikilinks:
Check out [this page](cerbo://123e4567-e89b-12d3-a456-426614174000) for details.Cerbo supports HackMD-style semantic annotations:
[Bob]{schema:Person} works at [Acme Corp]{schema:Organization}.These are extracted to annotations.ttl in Turtle RDF format.
Cerbo now uses UUID-based storage (.cerbo/objects/<uuid>/). This is a breaking change from the previous slug-based model.
To migrate an existing vault:
# Dry run - see what would be migrated
cargo run --package cerbo-migrate -- migrate --dry-run
# Actual migration
cargo run --package cerbo-migrate -- migrate
# Verify migration
cargo run --package cerbo-migrate -- verifyThe migration tool will:
- Copy
page.mdto.cerbo/objects/<uuid>/page.md - Copy
assets/directory to.cerbo/objects/<uuid>/assets/ - Copy any other files in the page directory
- Generate new UUIDs for each page
- Create
meta.ttlwith object metadata
After migration, regenerate backlinks and annotations with:
cerbo indexCreate a new vault in the current directory:
cerbo initThis creates a .cerbo/ directory with the necessary structure and bundles standard ontologies (Schema.org, FOAF).
# Create a new page
cerbo page create "My First Page"
# Output: Created page: 550e8400-e29b-41d4-a716-446655440000
# List all pages
cerbo page list
# Read a page
cerbo page read 550e8400-e29b-41d4-a716-446655440000
# Write content to a page
cerbo page write 550e8400-e29b-41d4-a716-446655440000 "New content"
# Delete a page
cerbo page delete 550e8400-e29b-41d4-a716-446655440000The cerbo index command rebuilds metadata (backlinks and annotations) from page content. This is useful after:
- Manually editing
page.mdfiles outside of Cerbo - Bulk imports or vault migrations
- If backlinks or annotations appear stale or missing
- To verify metadata integrity after crashes or interruptions
# Rebuild all metadata for the current vault
cerbo index
# Rebuild metadata for a single page (incremental)
cerbo index --page 550e8400-e29b-41d4-a716-446655440000
# Index a vault from outside its directory
cerbo index --vault /path/to/my/vault
# Get indexing statistics as JSON
cerbo index --jsonThe index command uses Git-style vault discovery: it walks up from the current directory looking for a .cerbo/ directory. You can run it from any subdirectory within a vault.
The cerbo symlink command builds a human-readable directory tree at <vault-root>/cerbo/ using symlinks into the UUID object store. This lets you browse and navigate your notes by slug name instead of raw UUIDs.
# Build (or rebuild) the symlink tree from the current vault
cerbo symlink
# Build from an explicit vault path
cerbo symlink --vault /path/to/my/vault
# Get a JSON report of what was created
cerbo symlink --json- Symlinks are always relative (portable when the vault is moved)
- Pages without a
cerbo:slugare skipped — runcerbo indexfirst to backfill slugs - The tree is rebuilt atomically, so reads always see a consistent state
cerbo initadds/cerbo/to.gitignoreautomatically
Pages can be nested via the cerbo:virtualPath metadata field:
cerbo/
├── my-notes → .cerbo/objects/<uuid>/
├── research/
│ ├── rust-ownership → .cerbo/objects/<uuid>/
│ └── async-patterns → .cerbo/objects/<uuid>/
└── projects/
└── cerbo → .cerbo/objects/<uuid>/
# Import a webpage as a source object
cerbo import https://example.com/article
# Import an ontology
cerbo import-ontology https://schema.org/version/latest/schemaorg-current-https.jsonld# List all registered vaults
cerbo vault list
# Add a vault
cerbo vault add "Work Notes" /path/to/work/vault
# Remove a vault
cerbo vault remove <vault-id>
# Set active vault
cerbo vault active <vault-id># Resolve UUID to filesystem path
cerbo resolve 550e8400-e29b-41d4-a716-446655440000
# Show configuration
cerbo infoLGPL-3.0-or-later