Self-hosted service
silverbulletmd/silverbullet avatar
silverbulletmd/silverbullet

SilverBullet: A Self-Hosted Markdown Knowledge Base Programmed in Lua

An open source personal productivity platform built on Markdown, turbo charged with the scripting power of Lua

6,207 stars498 forksTypeScriptMIT

At a glance

What is it?
SilverBullet keeps your notes as Markdown files on your own server and adds a query language and an embedded Lua runtime on top. It is a good fit if you want to script your notes; it is a poor fit if you want a hosted service or a mobile-first editor.
Who is it for?
Adopt SilverBullet if you are comfortable running a server and want a Markdown space you can query and extend with Lua, and if you are willing to accept a browser-based client and a thin documented upgrade path. Do not adopt it if you need a hosted service, a native mobile app, or a team product with role-based permissions; the README describes a personal knowledge database, not a collaboration platform.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 3, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What SilverBullet solves, and who it is built for

Most note tools force a choice. Either your notes live in a plain folder of Markdown files and you give up structure, or they live in a database and you give up portability. SilverBullet takes the first option and adds the second on top: the README describes the content as "a collection of Markdown Pages (called a Space)", and separately advertises "a built-in database and query language". The files stay files. The index and the queries are derived from them.

The intended user is stated fairly openly. The README sorts readers into personality types: the writer gets a live-preview Markdown editor, the outliner gets outlining tools, the task-management user gets Tasks, and the database-minded user gets Objects and Queries, abbreviated SLIQ. Then it addresses the last group directly: "if you are comfortable programming a little bit", you can generate content dynamically with Space Lua, or use it to build custom commands, page templates and widgets. That is the real audience. SilverBullet is for one person who owns a server, keeps notes in Markdown, and is willing to write a few lines of Lua when the built-in behaviour is not enough.

It is not aimed at teams. Nothing in the README describes shared editing, comment threads, permissions or an audit trail. The server handles authentication and serves a space; the product framing is a personal one.

How SilverBullet works: a Rust server, a browser client, and Lua in between

The repository layout makes the architecture unusually legible. The frontend lives in client/ and is written in TypeScript on top of CodeMirror 6, with Preact for additional UI and ESBuild as the bundler. The backend is a Rust Cargo workspace. The README lists its members plainly: server/ holds the HTTP router, handlers, auth and what it calls the "runtime seam"; server-common/ holds shared space primitives and types; server-runtime-chrome/ is a headless-Chrome runtime backend. The binary you actually run, bin/silverbullet/, serves the pre-built client bundle, the file and space HTTP API, authentication, and that headless-Chrome runtime for server-side Lua. There is also a separate sb CLI client in bin/sb/.

The split explains a behaviour that would otherwise look strange. The README says a debug build "serves the client bundle live from client_bundle/ on disk", while a release build embeds it. So during development you can rebuild only the TypeScript and reload the browser without restarting the server. In a release binary the client is baked in, which is why the Makefile has a separate target for end-to-end tests against embedded assets.

The Lua story has two halves. Client-side scripts run in the browser. Server-side Lua needs an actual browser engine, which is why Chromium is a runtime dependency of the default container image rather than an optional extra. The Dockerfile for the slim variant states this consequence directly: with no Chromium, requests under /.runtime/* return 503. If you plan to use server-side Lua, that is the difference between the two images.

Installing SilverBullet from Docker and opening your first space

The README does not inline installation steps; it points to a page at silverbullet.md/Install. What the repository itself documents are the build and container paths, and those are enough to get a working server.

The Dockerfile builds an image whose entrypoint runs the server under tini, with SB_HOSTNAME defaulting to 0.0.0.0 and SB_PORT to 3000, and a healthcheck that curls /.instance on that port. The README gives the build and run commands:

bash
docker build -t silverbullet .
bash
docker run -p 3000:3000 -v <PATH-TO-YOUR-DATA-FOLDER>:/data silverbullet

The image notes that the data folder can only be set through SB_FOLDER, and that the entrypoint resolves it to /data, or to the legacy /space if it is unset. The mount in the second command is what makes your notes survive a container rebuild, so point it at a real directory. The Dockerfile also mentions that extra arguments, for example --single, are passed through to the server.

If you would rather run a binary, the Makefile installs the server and the CLI from source into your Cargo bin directory:

bash
make setup
make
./target/release/silverbullet <PATH-TO-YOUR-DATA-FOLDER>

The first command installs npm dependencies and the Playwright browsers; make builds the client bundle, the plug compiler, and release binaries for silverbullet and sb into ./target/release/. After the server starts, open the port in a browser and you should land in the page picker, with your space backed by the folder you passed.

The Chromium dependency and other places SilverBullet will not fit

The most concrete limitation is the one the project documents about itself. The default image layers Chromium on top of the slim one, and the slim Dockerfile says plainly that without it, /.runtime/* returns 503. That means the lightweight image is not a full SilverBullet: anything relying on server-side Lua fails at request time rather than at startup, which is a worse failure mode because the container looks healthy. The healthcheck only tests /.instance, so it will not catch this.

A second constraint is the client. SilverBullet is a browser-based editor. The README's own adjective list starts with "Browser-based", and there is no desktop or mobile application described in the repository. You get a web UI, and on a phone that means a browser tab. Whether that is acceptable depends entirely on how you take notes away from a desk.

Third, the versioning is worth reading carefully. The package version is 2.11.0, and the search data shows people asking about "SilverBullet v2", so the 2.x line is the current one. Nothing in the README or the Cargo workspace describes a migration path between minor versions of a space, or a rollback procedure if an upgrade goes wrong. Your Markdown files are plain text, which is the real safety net, but any Lua libraries, plugs or page templates you write against the scripting API are your own to maintain across releases.

Finally, this is a personal tool by design. If two people need to edit the same space at once, or if you need per-page access control, SilverBullet's documented surface does not offer it.

SilverBullet compared with Obsidian and Logseq

The obvious comparison is with local-first Markdown editors that store notes as files. Obsidian is the closest match on storage: a vault of Markdown files on your disk, with a plugin ecosystem for extension. The difference is where the code runs. Obsidian is a desktop application with an optional paid sync service; its plugins are JavaScript and execute in the app. SilverBullet is a server you host, reached through a browser, and its extension language is Lua, with a TypeScript plug API published to npm as @silverbulletmd/silverbullet. If you already think in JavaScript, Obsidian's model is the shorter path. If you want one server holding your space and reachable from any browser you control, SilverBullet's model is the more direct one.

Logseq takes a different position again: outliner-first, with blocks rather than pages as the primary unit. SilverBullet supports outlining, but its README presents pages as the container and queries over objects as the way to get structure back. The two tools disagree about what the atom of a note is, and that disagreement shows up in everything downstream.

The honest summary is that SilverBullet's differentiator is not the editor. It is the combination of a self-hosted Rust server, a Markdown space, and a Lua runtime that can generate page content and define commands. If you do not intend to write any Lua, the scripting half of the product is dead weight for you, and a plain Markdown editor with a sync folder would do the same job with less to operate.

Licence, build cost and what upgrading actually involves

SilverBullet is MIT licensed, and the Cargo workspace declares license = "MIT" for the workspace package. MIT is permissive: you can run it, modify it and redistribute it, including in a commercial setting, provided you keep the copyright notice and licence text. The repository ships LICENSE.md at the top level. This is a description of the licence, not legal advice; if you plan to redistribute a modified build, read LICENSE.md yourself.

The operating cost is a server and, for the default image, a Chromium process. That is the heaviest single line item. If you do not need server-side Lua, the slim variant from Dockerfile removes it, at the price of the 503 behaviour described above.

Building from source is not trivial, and the README is candid about why: you need Node.js 24 or newer with npm 10 or newer for the client and plugs, plus a stable Rust toolchain via rustup for the server. The repository includes .nvmrc and .node-version, so a Node version manager picks the right version automatically. The Makefile exposes make check for typechecking and linting, make test, make bench, and make clean. CI runs cargo clippy with warnings as errors, which is why the workspace lint policy is configured centrally in Cargo.toml.

On upgrades, the material is thin. There is a CHANGELOG.md at the top level and releases are tagged, with 2.11.0 published on 2026-09-17, 2.10.0 on 2026-07-28 and 2.9.0 on 2026-06-11. That cadence is roughly every six to eight weeks. Nothing documents a downgrade path. The practical position is that your notes are Markdown files you can read without SilverBullet, but your Lua and any plug code are tied to the version you wrote them against, so pin a version you have tested rather than tracking the newest tag.

Editorial conclusion

Adopt SilverBullet if you are comfortable running a server and want a Markdown space you can query and extend with Lua, and if you are willing to accept a browser-based client and a thin documented upgrade path. Do not adopt it if you need a hosted service, a native mobile app, or a team product with role-based permissions; the README describes a personal knowledge database, not a collaboration platform. Before committing, verify two things on your own machine: that the Docker image you pull actually includes the Chromium runtime (the slim variant returns 503 under /.runtime/*), and that the release binary you download matches your architecture, since the CI build produces amd64, arm64 and armv7 artifacts separately.

Frequently asked questions

What is SilverBullet software?

It is a self-hosted, browser-based personal knowledge database that stores your content as Markdown pages in a space. The README describes it as a Markdown editor programmable with Lua, with wiki-style links, a query language and an integrated scripting environment.

How do I install SilverBullet?

The README does not list install steps inline; it points to silverbullet.md/Install. The repository documents building the image with docker build -t silverbullet . and running it with docker run -p 3000:3000 -v <PATH-TO-YOUR-DATA-FOLDER>:/data silverbullet, or building release binaries with make.

Does SilverBullet need Chromium to run?

Only for server-side Lua. The slim Dockerfile states that without Chromium, requests under /.runtime/* return 503, which is why Dockerfile.runtime-api layers Chromium on top to create the default image.

What programming language does SilverBullet use for scripting?

Space Lua, described in the README as SilverBullet's Lua dialect. It is used to generate content dynamically and to create custom commands, page templates and widgets. Separately, plugs are written in TypeScript against the plug-api package.

What are the build requirements for SilverBullet from source?

The README lists Node.js 24 or newer and npm 10 or newer for the frontend and plugs, and a stable Rust toolchain installed via rustup for the server. The repository includes .nvmrc and .node-version files so a Node version manager selects the right version.

What licence is SilverBullet released under?

MIT. The Cargo workspace declares license = "MIT" for the workspace package, and LICENSE.md sits at the top level of the repository.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. silverbulletmd/silverbullet on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/silverbulletmd-silverbullet.svg)](https://hysenlabs.com/projects/silverbulletmd-silverbullet)