How silverbulletmd/silverbullet works
1. Overall shape
SilverBullet is a two-part system: a browser client written in TypeScript and a Rust backend that serves the client, stores/serves the space, and runs server-side services. The product is a local-first notes/database app centered on Markdown pages, but the architecture is closer to a programmable runtime than a conventional web app.
2. Client runtime in the browser
The client/ tree contains the main application logic: editor, navigation, page picker, command palette, datastore abstractions, sync engine, service worker, and the Space Lua runtime. The frontend is built on CodeMirror 6 for editing, Preact for UI, and ESBuild for bundling. In practice, much of the app behavior lives in the client rather than the server.
3. Editor and content pipeline
The editor pipeline spans Markdown parsing/rendering, live preview, code widgets, wiki links, tables, tasks, and custom syntax. The client transforms raw page text into structured views and editor decorations, then back into document edits. This is the core interactive loop for page editing.
4. Local-first data model
The client/data/ and client/spaces/ modules show that the app has a layered local storage model: in-memory, IndexedDB, encrypted variants, and sync-aware datastore primitives. A service worker and sync engine coordinate offline operation and eventual synchronization with the server. This makes local browser state a first-class boundary, not just a cache.
5. Space abstraction and synchronization
The repository models a “Space” as the unit of content and synchronization. client/spaces/ implements checked, filtered, HTTP-backed, evented, and datastore-backed space primitives, while server-common/src/space/ provides the corresponding Rust-side implementations for disk, memory, HTTP, readonly, and embedded spaces. This is the main persistence boundary in the system.
6. Server responsibilities
The Rust server/ crate is the HTTP/control plane. It provides routing, authentication, filesystem access, runtime endpoints, shell access, SSR, metrics, and bundle serving. The server is not the primary application engine; it is the host for static assets, authenticated access, and server-side capabilities.
7. Authentication and access control
server/src/auth/ contains login, cookies, JWT authorization, headless tokens, lockout, and authorizer/authenticator logic. This indicates a security boundary around space access and administrative control, with the server enforcing identity before exposing file and runtime APIs.
8. Server-side runtime and Lua execution
SilverBullet includes a server runtime for executing Space Lua outside the browser. server-runtime-chrome/ manages a headless Chrome-based runtime backend, supervised and transported from Rust. This is important because many programmable features depend on executing Lua with DOM/runtime-like capabilities in a controlled environment.
9. Plugin system as the extension boundary
The plugs/ directory contains built-in plugs that implement major product features such as editor enhancements, indexing/querying, configuration management, sync, emoji, image viewing, and object graph visualization. Plugs are compiled and packaged separately, and they extend the app through the PlugOS API rather than by patching the core.
10. PlugOS and syscall boundary
client/plugos/ and plug-api/ define the plugin protocol, syscall interfaces, sandboxing, manifests, and runtime hooks. This is a critical architectural seam: plugs run in isolated sandboxes and interact with the host through typed syscalls for datastore, editor, markdown, shell, config, sync, and related services.
11. Shared Rust foundations
server-common/ is the shared Rust crate for cross-cutting types, crypto, upgrade logic, and space primitives. It keeps the backend binaries aligned and prevents duplication between the server and the standalone runtime-related components. This shared layer is the low-level foundation under the HTTP server and embedded space handling.
12. Build and distribution pipeline
The repo is organized around separate build products: the TypeScript client bundle, built plugs, and Rust binaries. bin/silverbullet is the main self-hosted server binary, bin/sb is the CLI, and the various Dockerfiles/package scripts support release packaging. A release build embeds the client bundle into the Rust binary, while debug development serves the bundle from disk.
13. Documentation and libraries as shipped content
docs/ and libraries/ are not just documentation; they are part of the shipped content model. The libraries provide built-in page templates, slash templates, and Space Lua references that become part of the user space experience. That makes “content” an architectural artifact alongside code.
14. Key runtime flow to diagram
A useful high-level flow is: browser loads the bundled client from the Rust server → client opens a Space via local storage and/or HTTP sync → edits update the local datastore immediately → sync propagates changes to the server space backend → plugs and Space Lua augment behavior through syscalls and runtime services → server optionally executes Lua/headless services and returns results to the client. This captures the main data and control paths without overfocusing on any one subsystem.
Main entry points: protocol.ts PlugOS · client.ts Client app · lib.rs Server · space_primitives.ts Spaces
Components 24
Client runtime
Browser-side TypeScript application, editor, storage, sync, and client-side runtime
- Boot · Initial browser startup, config loading, and app wiring
client/boot.ts - Client app · Main client orchestration and application state
client/client.ts - Editor · Document editor, commands, UI, and CodeMirror integration
client/document_editor.ts - Markdown · Markdown parsing and rendering pipeline for pages and decorations
client/markdown_parser/parser.ts - Datastore · In-memory, IndexedDB, encrypted, and sync-aware data primitives
client/data/datastore.ts - Spaces · Client-side space primitives, filtering, HTTP access, and sync
client/spaces/space_primitives.ts - Service worker · Offline proxying and sync engine coordination
client/service_worker/sync_engine.ts - Space Lua · Client-side Space Lua parser, evaluator, and standard library
client/space_lua/runtime.ts - PlugOS · Client plug protocol, sandboxing, hooks, and syscalls
client/plugos/protocol.ts
Plugs
Built-in extensions and their plug/runtime boundaries
- Core plugs · Built-in editor, index, sync, and UI extension packs
plugs/builtin_plugs.ts - Editor plug · Navigation, outline, page tools, and editor augmentation
plugs/editor/editor.ts - Index plug · Content indexing, query support, and structured document extraction
plugs/index/indexer.ts - Sync plug · Synchronization feature glue on the plug side
plugs/sync/sync.ts - Config manager · User configuration and shortcut management UI
plugs/configuration-manager/configuration.ts - Object graph · Object graph visualization and model building
plugs/object-graph/src/object_graph.ts
Rust backend
Server, shared Rust foundations, and headless runtime support
- Server · Rust HTTP server, routing, static assets, and control plane
server/src/lib.rs - Auth · Login, cookies, JWT, headless tokens, and access control
server/src/auth/mod.rs - Runtime · Server-side runtime backend, transport, and log handling
server/src/runtime/mod.rs - Shell · Shell command execution and related handlers
server/src/shell.rs - Space core · Shared Rust space primitives for disk, memory, HTTP, readonly, and embedded spaces
server-common/src/space.rs - Chrome runtime · Headless Chrome supervisor and transport for server-side Space Lua execution
server-runtime-chrome/src/supervisor.rs
Shipped content
Docs, libraries, and templates that ship with the product
- Docs · Architecture, API, and user-facing documentation shipped with the repo
docs/index.md - Libraries · Built-in page templates, slash templates, and standard libraries
libraries/Library/Std.md - Space template · Default space template embedded into release builds
bin/silverbullet/space_template/index.md
Connections 28
- Boot → Client app: starts · Boot code initializes the application shell
- Client app → Editor: hosts · The app wires editor state and interactions
- Client app → Spaces: opens · App works against the active space abstraction
- Editor → Markdown: renders · Editor uses markdown parsing/rendering for live view and decorations
- Editor → Datastore: edits · Edits update the local datastore immediately
- Datastore → Spaces: backs · Datastore primitives are wrapped by space primitives
- Service worker → Spaces: proxies · Service worker routes offline and sync-aware space access
- Service worker → Datastore: syncs · Offline engine coordinates local persistence and reconciliation
- Client app → Space Lua: runs · Client embeds Space Lua for programmable behavior
- Client app → PlugOS: loads plugs · Application hosts the plug runtime and hook registry
- PlugOS → Core plugs: executes · PlugOS loads built-in plugs through manifests and hooks
- PlugOS → Editor plug: extends · Editor-related plug contributes commands and navigation features
- PlugOS → Index plug: extends · Index plug provides structured extraction and query features
- PlugOS → Sync plug: extends · Sync plug hooks into synchronization behavior
- PlugOS → Config manager: extends · Config manager is delivered as a plug
- PlugOS → Object graph: extends · Object graph visualization is packaged as a plug
- Server → Auth: enforces · Server protects access with authentication and authorization
- Server → Space core: serves · Server exposes space-backed content and APIs
- Server → Runtime: hosts · Server provides runtime endpoints and transport orchestration
- Server → Shell: exposes · Server provides shell access endpoints
- Server → Chrome runtime: supervises · Server delegates headless execution to the Chrome runtime
- Runtime → Chrome runtime: executes lua · Server runtime uses the headless backend for controlled execution
- Space core → Spaces: sync target · Client space primitives sync with the server-side space implementations
- Spaces → Space core: http sync · Browser space access can be backed by HTTP-served spaces
- Client app → Server: fetches bundle · Browser loads the client bundle and assets from the server
- Docs → Client app: explains · Docs describe the client model and user-visible workflows
- Libraries → Space Lua: extends · Libraries ship standard Space Lua APIs and templates
- Space template → Server: embedded in · Default starter space is packaged into release artifacts