An attempt at documenting the changes/new features introduced in each release.
Edge
Whenever a commit is pushed to the main branch, within ~5 minutes, it will be released as a docker image with the :v2 tag, and a binary in the edge release. If you want to live on the bleeding edge of SilverBullet goodness (or regression) this is where to do it.
- Fix: long-lived plug panels (sidebars, preloaded modal panels) kept the light/dark theme they booted with — switching theme mid-session only reached panels that happened to be rebuilt afterwards. They now follow the theme as it changes.
- Fix: a plug panel’s iframe sat on the text baseline as an inline element, so every panel added a few pixels of overflow to the app layout. Nothing showed a scrollbar, but the page stayed scrollable, and content inside a panel scrolling itself into view could shove the whole app up underneath the top bar.
- Live external edits: changes made to pages by other programs (or users, but don’t rely on this for real-time collaboration) now show up in an open pages almost instantly, instead of waiting for the next sync. The client applies them to the open page as minimal, cursor-preserving edits that land in the undo history, so
Cmd/Ctrl-zreverts an external edit like any other. The externally inserted text is briefly highlighted with a marker showing where it landed, fading after a few seconds.- This relies on active file-system, watching which can be configured server-wide with the new
SB_FS_WATCHenvironment variable (auto(default) /poll/off): setpollwhen the space lives on a network mount (NFS/SMB) where changes made may not result in FS events.
- This relies on active file-system, watching which can be configured server-wide with the new
- Inline comments (Comment): any HTML comment (
<!-- remember this -->) is now a parsed and rendered as a note. - Multi-space mode: the Runtime API (
runtimeApi) is now on by default for new and existing spaces, instead of off. It only actually runs when the server found a Chrome or Chromium install at startup and only booted upon first use of the API. - Space Manager: saving an edited space now returns to the space list, instead of staying on the edit form with a brief “✓ Saved” confirmation. Creating a space still lands on the new space’s own screen.
- Fix: a markdown table whose column happens to be named
ref,tag,tags,itags,pageortablerefno longer overwrites the indexed row’s own identity. Such a column re-typed the row as whatevertagsaid and gave it therefin that cell, so the row silently replaced the real object it named — a table with atagcolumn readingpageclobbered that page’s index entry, leaving it with atagsstring instead of a list and breaking every picker withx.tags.map is not a function. These columns are now ignored for indexing (asposandrangealready were); the table still renders them normally. - Fix: the Runtime API’s headless Chrome crashed and restarted every few seconds on the
-runtime-apidocker image, spamming the server log (and the host’s console with core dumps) and leaving the API only intermittently available. Chromium 150 fails to initialize its GPU stack inside a container, which was fatal to the whole browser because it was launched with--in-process-gpu. (#2078) - Fix: the docker image ignored
PUID/PGIDand space folder ownership, running asrootand creating root-owned files - Fix: the
:latestdocker tag pointed at the ~1.2GB Chromium-bearing-runtime-apiimage instead of the ~90MB base image (#1994) - Building from source is a little cheaper: the
zipdependency (used only to unpack our own release archives during self-upgrade) no longer pulls in the zstd, lzma, bzip2 and xz decoders. That drops 18 crates — three of which compile bundled C — for ~25 CPU-seconds off a clean build, and three fewer things to keep working across the cross-compile targets. - Fix: the FreeBSD server binary is being built and released again
- Fix: multi-space mode silently ignored
SB_REMEMBER_ME_HOURS,SB_LOCKOUT_TIME, andSB_LOCKOUT_LIMIT, hardcoding “remember me” sessions to 7 days and lockout to 10 attempts per minute. All three now apply there too — server-wide, like the session itself — matching what Configuration documents. - Multi-space servers now share a single headless Chrome across all spaces instead of launching one browser per space.
- Fix: the Runtime API failed to start when authentication was enabled.
- Fixes around casing in page/file names:
- Renaming a page or folder to a different casing of the same name now works on case-insensitive filesystems (macOS, Windows)
- Renames are now rejected when the new name differs only in casing from an existing page or document, so spaces stay portable between case-sensitive and case-insensitive hosts.
- On case-insensitive filesystems, writing a file whose folder differs only in casing from an existing one now re-cases that folder to match — so writing
notes/foowhen the disk holdsNotes/renames the folder, changing the reported path of every page inside it.
2.10.0
- Space Manager: multi-space hosting with multiple accounts is here. A fresh install pointed at an empty folder opens a browser-based first-run setup wizard that creates an admin account and your first space, then serves it in place with no restart. One server can host any number of spaces, each bound to a URL prefix or hostname.
- Baked Sections: bake ```````````````````````````` widgets into
HTML-comment-delimited markdown (
<!--#lua EXPR -->…<!--/lua-->). - Space Lua: code complete now shows documentation (where available), all available via spacelua reflection APIs.
- Backend and CLI have been ported to Rust (see background on this), both should be behavior preserving (that is: you shouldn’t really notice):
- The server backend (previously written in Go) has now been replaced by an adapted version of SilverBullet+’s backend written in Rust, more unifying those code bases.
- CLI client reimplemented/back-ported to Rust as well.
- This means the project is now all TypeScript + Rust.
- Frontmatter in the editor now has configurable folding: by default long frontmatter blocks fold automatically, and
frontmatterFoldingoptions let you disable auto-folding, always fold frontmatter, or change the line threshold. A subtle right-side marker folds or unfolds the whole block, and folded frontmatter previews anytagsvalue as tag chips. This is configurable via the Configuration Manager as well. - Page Picker: type
$to switch to anchor navigation - Pulling the “this was experimental card” for the CLI: removed the
sb getcommand and the/.runtime/objects/*REST API, including their dedicated client-side query bridge. Usesb query,sb eval, orsb scriptfor indexed-object access. This added too much complexity and another query language. - Fix:
SB_SHELL_BACKEND=localdisabled shell command execution instead of enabling it. - Fix: a
range(orpos) attribute in your own content could overwrite the source offsets an indexed object uses to point back at its place in the page. - Fix: only the first entry of a frontmatter list of wiki links formed a relation (e.g. an
authors:list of[[...]]items), so every entry after the first was missing from Object Graph, linked mentions and rename refactoring. - Fix: writing to a read-only path (anything served from the bundled library, a
SB_READ_ONLYserver) returned a 500, which clients could not tell apart from a temporary server fault — so a syncing client retried it forever. Read-only refusals now return 403, and the sync engine records the path and stops re-attempting it until the local file changes. This most often bit spaces holding a stale copy of aLibrary/Stdpage that a later release had dropped from the bundle. - Fix: major typing/navigation slowdown on pages with many internal links in large spaces.
- Fix: the service worker precached client assets through the browser’s HTTP cache, so a stale client could be copied into its cache and then served as though it were the current build — leaving a “A new version of SilverBullet client is available.” notification that no reload could clear (only a hard reload, which bypasses the service worker, showed the real client; the next normal reload brought the notification back). Precaching now bypasses the HTTP cache.
- The server now sets
Cache-Controlon client assets, which matters if you run SilverBullet behind a CDN. - Lua: Space Lua comments are now parsed and retained in the AST instead of being stripped before parsing (part of the enabler for code complete with documentation).
- Fix: first-ever load of an authenticated space no longer shows a spurious “Could not process config and no cached copy, please connect to the Internet” alert before redirecting to the login page (the login redirect aborted the remaining boot requests, which were misread as being offline).
- Fix: frontmatter link live preview now follows the editor’s regular markdown preview behavior: raw YAML syntax stays visible when markdown syntax rendering is enabled, and only the link currently being edited is revealed in clean mode.
- Fix: write-mode commands (those requiring read-write, e.g. the baking commands) are now hidden in the command palette and their keybindings disabled on per-page read-only pages (
perm: ro), not just in fully read-only spaces. - Runtime API: the embedded headless-Chrome runtime now logs its lifecycle (when it launches on first use, when it becomes ready, and on crash/restart), and forwards the headless page‘s
console.*output to the server log by default (disable withSB_CHROME_LOG_CONSOLE=0see Configuration). - New codeWidget Lua API: register a renderer for a fenced code block language from Lua (e.g.
```mermaid), previously only possible with plugs. Arender(body)function receives the code block contents and returns a widget (or markdown/HTML). - HTML comments (both inline
<!-- ... -->and block comments, including the baked-section<!--#lua … -->/<!--/lua-->markers) now render in a subtle gray and slightly smaller font in the editor, like code comments. - Fix: Space Lua now correctly truncates a parenthesized expression to a single value (Lua 5.4 semantics). Previously
(string.gsub(...))and other parenthesized multi-return calls leaked their extra return values intoreturn, call-argument, and assignment positions (e.g.table.insert(t, (string.gsub(...)))inserted two elements). Parentheses now yield exactly one value. - Fix: Lua pattern matching lost capture groups, because
ipairsdroppednilvalues from the result table (by henrikx). - Fix:
lintObjectsthrew when a page’spageMetawas undefined (by josh-j). - Fix:
mq.pollmaterialized the entire queue on every poll (by josh-j). - Fix: on Safari/WebKit, the first keystroke right after a paste could be inserted at the wrong position (e.g. pasting a URL inside
[text]()and then pressing)produced[text]()url)instead of typing over the closing bracket). WebKit left the typing caret at the pre-paste position; the editor now re-syncs it after a paste. - Navigating to a page via a link now always opens it fresh (at the top, or at an explicit
#header/@pospointer in the link) instead of restoring your previous cursor and scroll position. Returning to a page via browser Back/Forward or the Page Picker still restores where you were. Plugs/Lua can opt into restoring with the neweditor.opensyscall (see editor). - Fix: modals now set
box-sizing, so their padding no longer pushes content past the intended width (by Federico Scodelaro). - Favicon definitions cleaned up and documented following current best practices (by Jorge Marin).
- The server now compresses
GETresponses, reducing transfer sizes over slow connections.
2.9.0
- New relation indexed object capturing generalized object-to-object relationships. This is a successor to link, which still exists as a virtual collection built on top of
relation. - New experimental Object Graph: an interactive, force-directed graph explorer over the relation index. Try it via ${widgets.commandButton(“Graph: Explore”)} and ${widgets.commandButton(“Graph: Global Page Map”)}.
- Picker fuzzy search: replaced Fuse.js with a custom scorer that supports multi-token queries, path-aware ranking, and some typo tolerance.
- UX: a lot of little visual tweaks and usability fixes all over the place that hopefully will trigger less of your OCD, including:
- On narrow viewports (<800px) header
#markers no longer get pushed off-screen when the cursor enters a heading - Positioning of the page title is now (more) left-aligned with editor text.
- List/outline alignment: bullets, checkboxes and ordered-list numbers now line up in a clean column regardless of nesting depth, list type, or whether items are tasks, see Outline Stress Test.
- Note: potentially breaking CSS change for theme authors: per-nesting-level indent values previously carried by
.sb-line-ul.sb-line-li-N,.sb-line-ol.sb-line-li-N,.sb-line-taskand.sb-line-blockquote.sb-line-li-Nselectors have been removed.
- Note: potentially breaking CSS change for theme authors: per-nesting-level indent values previously carried by
- Task checkboxes are now drawn in CSS (
appearance: none+ bordered box + rotated-rectangle checkmark) instead of relying on the native checkboxes. Should improve rendering on webkit browsers, and gives more control over the width.
- On narrow viewports (<800px) header
- Start of shared UI components (between SB core and plugs): component styles (for buttons, inputs, selects, checkboxes, tabs, alerts, badges, progress bars), and a
@silverbulletmd/silverbullet/uipackage export providing optional Preact wrappers. See Reference for notes on how to use this as a plug author. Built-in plugs like Configuration Manager and Object Graph use these components already. In addition, these now also load Space Style inside the iframe, so components should become themable. - Technical simplification: replaced the CodeMirror-based mini-editor used in the page/command picker, prompt dialogs, and the top-bar page-name field with native text inputs, improving accessibility, mobile keyboard behavior, and removing several Safari/layout hacks.
- Potentially breaking CSS change for theme authors: these three fields are no longer CodeMirror instances, so any styling that targeted them via
.sb-mini-editor, the.cm-content/.cm-line/.cm-scrollerrules inside.sb-modal-box, or the.cm-scroller/.cm-contentrules under#sb-current-page, no longer applies. They are now native<input>elements sharing the.sb-inputbase class, each with a context-specific class to retarget:- Picker / command-palette filter:
.sb-input.sb-filter-input(inside.sb-modal-box .sb-header) - Prompt dialog input:
.sb-input.sb-prompt-input(inside.sb-prompt) - Top-bar page title:
.sb-input.sb-page-name-editor(inside#sb-current-page)
- Picker / command-palette filter:
- Potentially breaking CSS change for theme authors: these three fields are no longer CodeMirror instances, so any styling that targeted them via
- APIs:
- Space Lua: added
spacelua.prettyPrintBlock/spacelua.prettyPrintExpressionto pretty-print a parsed Lua AST back to formatted source. SupportsindentWidth,quoteandtrailingCommaoptions. In preparation of future functionality that will manipulate existing Lua code.
- Space Lua: added
index.contentPagesnow accepts an optionaltagargument to filter content pages by an additional tag, matching the other type-specific index helpers.- Fix: forced space reindex handling
- Fix: with two windows/tabs open on the same space, a full reindex (e.g. after an index-version bump) could deadlock IndexedDB.
- Fix: an interrupted full reindex (e.g. the window closed mid-reindex) no longer leaves the space permanently un-indexed.
- Fix: Clicking a wiki link to a page now places the cursor just after the page’s frontmatter on first visit (matching fresh-load behavior), instead of at position 0. Pages already visited in the session still restore their previously saved cursor position.
- Fix:
$-anchor refs now resolve through the index from every navigation path - Fix: Ctrl/Cmd-clicking a link inside rendered widgets (query/template results) now navigates in a new window via the normal navigation path
- Fix: tag autocomplete no longer triggers while typing markdown header prefixes (
##,###, etc.) - Internal: the legacy Go server and
sbCLI have been removed. The Rust server (silverbullet) and RustsbCLI are now the only implementations. No user-facing behavior change is expected.
2.8.1
- Fix: cursor and clicks no longer drift by a line or two when working below a tall widget (e.g. arrow-up from a list under a ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- Fix: arrow keys now reliably enter multi-line block widgets (queries, tables) line by line.
- Fix: Some finetuning of the markdown renderer.
- Fix: PWA boot no longer crashes silently when the server is unreachable and a boot-time file (e.g.
CONFIG.md) was previously 404 — the 404 result is now cached so subsequent offline boots succeed instead of throwing a rawTypeError: Failed to fetchthat the boot code swallowed. - New index query-collection helpers:
index.objects(the new alias forindex.tag), plusindex.pages,index.subPages,index.contentPages,index.metaPages,index.aspiringPages,index.tasks,index.headers,index.items,index.paragraphs,index.tables,index.documents,index.links, andindex.tags. Each type-specific helper takes an optional extra tag for filtering (exceptindex.subPages, which takes the parent page name, andindex.documents/index.links/index.tags, which take no arguments).
2.8.0
- X-Ray: an editor lens (run
Editor: Toggle X-Ray) to inspect indexed objects inline. - New built-in Journal library.
- Runtime API: Expose objects (with filter)
/.runtime/objects/*for external integrations and the CLI, see Runtime API. - New
SB_DISABLE_SERVICE_WORKER: server-side switch to disable the client service worker for all clients, this will disable sync (all loads and saves will go directly to the server) and disable any offline support. - UX: now showing spinners instead of underlying (Lua) code in states where widgets aren’t ready to render yet (e.g. before an initial index hasn’t completed)
- Fix: indexed
rangefordatablocks (and#tagdata blocks) now points at the YAML content instead of the surrounding fence markers; multi-document blocks now compute per-doc ranges correctly. sbCLI changed how it encrypts secrets, so if you used token or password-based auth you need to re-add your space.- Fix: indexed
rangeforspace-luaandspace-styleblocks now points at the inner code, not the```fences. - Fix: Page Templates are now fixed (required specifying of
suggestedNamebefore), now also supports objects as frontmatter - Removed: tapping the top bar (page name / action buttons area) no longer scrolls the editor to the top.
- Fix: page decoration prefixes now consistently appear in query-driven lists
- Fix: Safari/WebKit no longer renders block lua widget (queries, etc.) borders at the wrong position on first paint (previously required hovering or resizing the window to clean up).
- Fix: page navigation should now glitch less.
- Fix: browser back/forward now restores the scroll position you last had on each page.
2.7.0
- Configuration Manager: new UI for editing configuration, accessed via the
Configuration: Opencommand (Ctrl/Cmd-,) andConfiguration: Key Bindingscommands. This is a work in progress, but should already be a big improvement over the old ways. It currently supports:- Changing (common) configuration options
- Key binding management (oh my!)
- A Library manager, superseding the old Library Manager UI (which now has been removed)
- CLI renamed from
silverbullet-clitosb, in addition:- renamed
lua→eval luascript→script- a new
describecommand that describes SLIQ and lists tags with defined schemas.
- renamed
- New (experimental) Anchor syntax (
$name): a stable, space-globally unique name for (almost) any Object, referenced from links via[[$name]]. - Rebrand: “Lua Integrated Query” (LIQ) is now called Space Lua Integrated Query (SLIQ!) (as coined by Matouš Jan Fialka)
- API extensions for config:
config.definenow propagates schemadefaultvalues. Newconfig.defineCategory/config.getCategoriesAPIs, plus UI annotations for the configuration manager. Theui.orderschema annotation andconfig.defineCategory’sorderfield have been renamed topriorityand now sort descending (higher = appears earlier), matching the rest of SilverBullet’spriorityconventions. - Server no longer generates a default
CONFIG.mdin empty spaces, this page is now auto created by the configuration manager when required. - The legacy
plug-managerhas now been removed (superseded by the Library manager part of the Configuration Manager UI) - Development (now with new docs!) gains an optional
build:section in manifests, runningesbuild,sass, orcopytransforms before asset bundling — enables plugs to ship bundled TSX/SCSS UIs. - Keyboard shortcut for
Navigate: Homechanged toCtrl-Shift-h/Cmd-Shift-h - Action buttons: new
commandattribute foractionButton.define. When using this instead of aruncallback, keyboard bindings will appear in the tooltip. - Docker: removed
VOLUMEdeclaration from the Dockerfile (it gave a false sense of persistence/spacemust be explicitly mounted, as documented). This also fixed the silverbullet-website repo. - Fix: Sync now falls through to local data on browser-native network errors instead of returning 503; previously synced spaces serve locally immediately after a service worker restart.
- Fix: navigation no longer blocks while the initial index is still running.
- Fix: rich text paste only worked on the second try
- Fix: indexing blew up with malformed bullet list items
- Fix: regression where aspiring pages were not deleted once the page was created.
- Fix: auto complete of meta pages was broken
- Fix: page rename failed when the page contains external URL links.
- Fix: too-tall mini editor in various pickers on Safari.
- Security fix: auth cookies now set stricter security flags (HttpOnly, Secure, SameSite); auth config file corruption no longer fails silently.
- Potentially breaking CSS change for theme authors:
.sb-notificationshas moved in the DOM (notifications now portal todocument.body). - New system syscalls
system.loadPlug/system.unloadPlugfor per-path plug (re)loading. - New editor syscall
editor.focusfor explicitly focusing the editor. - Configuration Manager: Key Bindings tab now says “Filter commands” instead of “Search commands”.
- More sensible fallback values for config options before the initial index has populated defaults.
- Lint: the
nameattribute uniqueness check is now limited to#meta/librarypages. - Runtime API: better debug output when the headless Chrome instance fails to boot.
- Fix: more robust markdown tree traversal in the face of invalid markdown trees.
- Fix: outline operation edge cases.
- Fix: button text wrapping.
- Fix: Runtime API fixed for users using PUID and PGUID users (by Luminiferous348).
- Fix: symlinks inside the space directory are no longer accidentally removed when cleaning up empty parent directories after a file delete.
- Fix: slash commands now resolve the syntax node ending at the cursor, so they no longer get incorrectly suppressed adjacent to comment blocks or links.
- Fix: Service Worker is now built without
importstatements so it loads on Firefox versions before 147 (by Carlos Fdez. Llamas).
2.6.1
- Technical: Deno → Node.js migration: The TypeScript/client codebase has been migrated from Deno to Node.js, now using vitest for tests.
- Bundle size optimization: chunked builds with ESBuild, JIT loading of larger modules (vim, syntax modes).
- Runtime API and accompanying CLI (Experimental): programmatically interact with a (remote) SilverBullet server over via
silverbullet-clior a HTTP API: evaluate Lua expressions, run scripts, and retrieve console logs. Powered by a headless Chrome instance running the full SilverBullet client via CDP, so all results reflect live client state. - New query shortcuts:
index.contentPages()(pages excluding meta pages) andindex.metaPages()(only meta pages) for convenient querying without manual tag filtering. - Outlines commands have been thoroughly reworked. Should now be more robust and better tested outline move/indent operations. New features:
- Now also works with numbered items (and renumbers them)
- Now works with headers (moves around entire sections)
- Now works with paragraphs
- When ending an list item with a
:, and pressing Enter, the next item will be indented one level
- Markdown support enhancements:
- Footnotes: both reference-style (
[^1]) and inline (^[text]) footnotes with syntax highlighting, live preview on hover, reference completion, and invalid reference linting. - Live Preview for HTML tags
- Custom markdown syntax extensions (Experimental): define custom inline syntax via syntax that gets parsed, highlighted, and rendered in live preview.
- Footnotes: both reference-style (
- Space Lua enhancements:
- Performance: Lua interpreter hot-path optimizations, tree traversal and page index optimizations.
- Performance:
LuaTableinternals tuned for faster Lua execution.
- Space Lua/Integrated Query improvements (courtesy of Matouš Jan Fialka):
- Unified field list syntax for
from,select, andgroup byclauses, enabling multi-source cross-joins - Implicit single group for aggregates without
group by offsetclause support- Intra-aggregate
order bysupport - 13 new aggregate functions (
product,string_agg,yaml_agg,json_agg,bit_and,bit_or,bit_xor,bool_and,bool_or,stddev_pop,stddev_samp,var_pop,var_samp),aggregate.aliasAPI for custom aliases, andindex.aggregatesqueryable collection
- Unified field list syntax for
- Client upgrade notification: if the server is updated but the client version doesn’t match, a notification will appear instructing the user to reload.
- The ^Library/Std/Widgets/Widgets > Table of contents widget is now collapsible, defaults to open (by Dobli).
- Improved Lua widget rendering (by Matouš Jan Fialka): ```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
- Task
Task: Clean Completednow handles more scenarios, and leaves a cleaner outline. - Panels now use Shadow DOM elements instead of iframes (by onespaceman).
editor.flashNotificationnow supports an optional third argument withtimeout(use0for persistent notifications) andactions(buttons with callbacks).- Fix: table cell alignment for missing and misaligned cells
- Fix: handle tagged floats before plain object check in
renderCellContent(by Matouš Jan Fialka). - Fix: document file opening with URL prefix.
- Fix: autofocus on authentication page.
- Fix: mini editor regressions.
- Mobile: “lock” button to toggle read-only, useful for navigating without accidentally editing.
- Action Button enhancements:
standaloneoption: only show certain action buttons in standalone/PWA mode (e.g. forward/back navigation buttons)- Support for opting out action buttons from the mobile dropdown menu
- Fix: “No such header boot” errors in PWA mode.
- Fix: Edit buttons now work correctly for Lua expressions and code widgets whose bodies appear multiple times in the same page.
- Fix: attribute rendering.
- Fix: Markdown table rendering and removal of deprecated command button remnants.
- Task improvements (by Matouš Jan Fialka):
- Dropdown picker for custom task states with autocomplete and per-state CSS styling via
data-task-stateattribute - Improved task widget: toggle dropdown on re-click, narrowed decoration range for better cursor behavior
- Dropdown picker for custom task states with autocomplete and per-state CSS styling via
- API/shell > shell.run(cmd, args, stdin?):
shell.runnow accepts an optionalstdinparameter (by Brett Anthoine). - Sync: further edge case fixes (timestamp/content-length mismatch, service worker activation).
- Subtle breaking change:
template.eachnow returns an empty string on empty results instead ofnil. - Fix: only
#metaand#meta/prefixed tags are now considered meta tags, not e.g.#metabase. - Fix: TOC rendering when headers contain a numbered list item.
- Fix: edge case where the markdown link regex could go into infinite loop (links with escaped square brackets).
- Fix: unwrap multi-return values in PropertyAccess and method calls (by Brett Anthoine).
- Fix: allow colons in
SB_USERpassword (by Joshua Brunner). - Fix: mobile tasks caret jumping and empty widgets on navigation.
- Mobile: home button moved outside of the dropdown menu; hamburger menu style tweaks.
- Fix: extended task state widget click behavior and rendering in widgets.
- Fix: safer handling of default template files in non-empty spaces.
- Frontmatter
tags:key now has autocomplete support. - API/tag > tag.define(spec): new
tagPageattribute to customize where clicking a tag navigates to (defaults totag:name). - Fix: 32-bit ARM Docker builds.
- Fix: reduce visual bouncing when navigating between pages.
- Fix: encode URLs with dots in path names on WebKit/Safari (fixes opening e.g. PDF files).
- Vim mode: allow passing arguments to vim ex commands (by Felix Riedel).
- Tweaked default
indexandCONFIGpages for new installations. - Fix: tag stripping for page templates.
- Fix: widget glitching — widget HTML content is no longer cached (only heights), reducing storage usage and WebKit rendering issues.
2.5.0
- Changed keyboard bindings (sorry!). CodeMirror no longer directly allows
Alt-<letter>andAlt-<special-character>Keyboard Shortcuts, meaning I had to remap a few key bindings. It’s basically a mission impossible to pick great ones, but here are the new defaults:Quick noteis now bound to bothCtrl-q q(typeCtrl-qfirst, then hitqagain) andCtrl-q Ctrl-q(hitCtrl-qtwice)Navigate: Homeis now bound toCtrl-g hText: Markeris now bound toCtrl-Alt-m- Outlines commands generally now use a
Mod-.(Cmd-.on mac,Ctrl-.on Linux/Windows) prefix:Outline: Move Right:Mod-. lOutline: Move Left:Mod-. hOutline: Move Up:Alt-ArrowUpstill works, but now also addsMod-. kfor consistencyOutline: Move Down:Alt-ArrowDowstill works, but now also addsMod-. jfor consistencyOutline: Toggle Fold:Mod-. Mod-.Outline: * Fold(other fold commands): keyboard disabled, readd yourself if you need them (see Keyboard Shortcuts)Task: Cycle State:Mod-. t
Page: Renamekeyboard shortcut removedPage: Rename Linked Pagekeyboard shortcut removedSync: Spacekeyboard shortcut removed- As documented in Keyboard Shortcuts, it is now possible to specify multiple keyboard shortcuts to a commands.
- Sync reliability work:
- Better indication whether your page is synced to the server: “Dirty state” (slightly tinted color of page name) is now aligned with actual synced-to-server state unless the editor clearly indicates it is in offline mode (yellow top bar).
- Sync snapshots are now persisted after every file sync, reducing (and hopefully eliminating) edge cases where the sync engine is killed mid-sync (for whatever reason) and the snapshot becomes of sync with “reality”.
- The index status progress indicator (blue circle) should now be more reliably reflect the actual indexing status.
- HTTP status codes >= 500 are now treated as offline (better offline detection).
- Space Lua/Integrated Query improvements (courtesy of Matouš Jan Fialka):
- group by and
havingclauses with aggregator support filter(where <cond>)clause for per-row aggregate filteringnulls first/nulls lastinorder by- Null/missing query cells now render as empty
- group by and
- Space Lua engine general improvements (most courtesey of Matouš Jan Fialka):
- Native Lua pattern matching engine (replacing previous implementation)
- Support for
<close>attribute and __close metamethod - Better arithmetic error messages
- Refactor of control flow (performance)
- Improved numeric type semantics
- Implement
string.pack,string.unpackandstring.packsize - Implement
math.random,math.randomseed,math.tointeger,math.frexpandmath.ldexp - Implement
table.move; aligntable.packandtable.unpackwith Lua semantics - API/table > table.select(table, keys…) (non-standard in Lua) API, convenient to use in Space Lua/Integrated Query
selectclauses, see example in docs. - Extend
osmodule - Add
_VERSIONenvironment variable tostring()now respects__tostringmetamethod;#operator now respects__lenmetamethod- Fix:
table.sortcomparator,string.gsubtable replacement,math.modfreturn types, number formatting in..andtable.concat - Load order of scripts is now well defined:
order by (script.priority or 0) desc, script.ref
- New experimental API: API/tag > tag.define(spec), see linked page for docs and example uses. Brings back ability to define 📅 deadlines for tasks (see example). Another part of this is Schema support for tags. When a schema is defined for a tag, you get:
- Frontmatter attribute completion and linting (in-editor error indicators) for attributes defined as part of the tag’s schema.
- Space Lua/Integrated Query attribute code completion if you use the
from v = index.tag(“bla”)style syntax (so explicitly bind your iterator variable). - Item-level linting (highlights the object in-line in case of validation errors).
- Tag schema updates:
pos(present in link, item and some other tags) is now deprecated, userangeinsteadrangeis a tuple of two numbers: from and to (e.g.{0, 10}) identify where the object appears in the page
- Editor improvements:
- New
Page: Create Under Cursorcommand, useful to pre-create an aspiring page link. Put your cursor in a wiki link to a non-existing page, and hitCmd-Shift-Enter(Ctrl-Shift-Enter) to create it (empty) without navigating there. - Linked Mentions now list full page path rather than abbreviated version.
- Hide vertical scrollbar overflow for long page names.
- Upload file: prompt user before replacing files and no-clobber behavior for paste uploads (by Oliver Marriott).
- Trim user input from prompts where appropriate (by rktjmp).
- Consider empty string as invalid path (by rktjmp).
- New
- Styling changes:
- Attribute names and values ([key: value] notation) now get different CSS classes in the editor:
sb-attribute-namefor names andsb-attribute-valuefor values. - The
diffMarkdown/Fenced Code Block language now uses colors to indicate additions and removals (by Lajos Papp).
- Attribute names and values ([key: value] notation) now get different CSS classes in the editor:
- Configuration:
- New
shortWikiLinksconfig (defaulting totrue) that decides whether a wiki link should be rendered in its short form (rendering just the last segment, e.g.Person/Johnwould show asJohn). To always render the full name, putconfig.set(“shortWikiLinks”, false)in your CONFIG. - Authentication: how long “remember me” works is now configurable (by Metin Yazici) via Configuration and more reliably persisted.
- New
- Library Manager: SilverBullet now navigates to library page after installing one.
- Now excluding
.plug.jsand.js.mapfiles from the document list. - Fix: bring back Virtual Pages.
2.4.0
- Indexer rework (note: upgrading will start a full space reindex automatically):
- Performance: up to 2x faster
- Internal refactor, actually adding at least (rudimentary) unit tests now (imagine!)
itemandtasknow also index (wiki) links and inherited (wiki) links (links appearing in parent nodes), as requested here underlinksandilinks. Updated the “Linked Tasks” widget now to rely onilinks.- Rewrote snippet text for links (used in Linked Mentions) to be more contextual, now also includes child bullet items, see community discussion.
- For consistency with items,
taskrefsnow point to the item’s position resulting in a slight positional shift, if you have code relying on this, you may have to adjust it. - Disabled indexing all paragraph text by default, this caused significant indexing overhead. See discussion.
To re-enable:
config.set("index.paragraph.all", true) - Better link support in frontmatter (by Tomasz Gorochowik)
- The
page:indexevent now also receives atextandmetaattributes.
- Transclusions improvements:
- Now have an “eye” button to navigate to the transcluded location
- Transclusions now only live preview when the cursor is outside of them (as with other pieces of markup)
- Transclusions now properly support headers
- Items and tasks are now transcluded with their children (based on
@posnotation) (this is mostly helpful when used in queries)
- Page/document/meta picker tweaks:
- Upgraded the Fuse.js library and tuned the ranking parameters, hopefully leading to better results.
- Meta picker now more consistent with page picker
- You can now use
Alt-spaceto complete a folder matching the first result — try it and let me know how this works for you in practice.
- Built-in full-text search has been removed from the main distribution, this has now been moved to a separate repo (installable via the library manager). Rationale: full text indexing is expensive and the search results were quite bad. Recommendation: install Silversearch as an alternative.
- Tasks:
taskstateobjects are no more. Custom task states should now be defined using the taskState API.- Removed: deadline syntax (legacy syntax from v1) for tasks, please use attributes instead (e.g.
[deadline: "2026-01-01"]).
- New APIs:
- New commands:
Navigate: Copy Ref To Current PositionNavigate: Copy Link To Current Position
- Lua:
- SLIQ fix
- Ctrl-click navigate to definition on non-Mac operating systems
- Support for
<const>in Lua (by Matouš Jan Fialka)
- Production builds now include sourcemaps for easier debugging in browser DevTools. If you don’t want to serve sourcemaps publicly, you can block
*.js.mapfiles at your reverse proxy level (see TLS > Blocking sourcemaps). - Should now deal better with authentication layers (Cloudflare Zero Trust, Authelia, Pangolin)
- Sync errors now propagate better to the UI
- Document editors now fixed in Safari (by MrMugame)
%now supported in page names- Lua widgets “flapping” should now be less
2.3.0
This release (re)introduces Share, formalizes Library, and introduces in initial version of the Library Manager, a type of package manager for SilverBullet. It also progresses on Lua 5.4 compatibility.
Here’s what’s new:
- Share: a new mechanism to push content to external places and pull external content in (also used as the foundation of Library). This partially replaces many Export use cases. Export will be more for one-off use cases.
- Library: are now a more “real” thing, and can be distributed via the Library Manager and curated with Repository. For instructions on how to build your own libraries, see Development. Eventually, this mechanism will succeed the
plugsconfiguration andPlugs: Updatemechanism. Plug authors can already start to update their plugs to get ready, usually all that needs to be done is to add aPLUG.mdfile to their repository: example. - Service: a new mechanism used behind the scenes to power Share, but also Export and likely other features in the future. Built on top of Event.
- URI are now a more formalized and centralized mechanism, used by Share and likely other features in the future.
- Removed “Import” support, succeeded by Share.
- Tag Picker: to quickly navigate to tag pages
- Space Lua improvements (courtesy of Matouš Jan Fialka):
- Support for
goto(yes, I said I’d never add it, but Matouš did anyway) - Significant performance leaps
- Support \t in strings
- Support for
- More of an in-your-face error when you’re not using TLS and you should, with instructions how to fix it: even though using plain HTTP was never a supported configuration, it hard-broke in 2.2.1
- Plugs are now loaded from anywhere in the space, as long as they end with
.plug.js(so no longer need to be in_plug, in fact all shipped core plugs are now mounted underLibrary/Std/Plugs) - Automatically follow system dark mode (by Lelouch He)
- Fix Youtube embes (by Rodolfo Souza)
Upgrade notes:
- If you have third-party plugs installed and intend to reinstall them as Libraries: be sure to delete the old versions first. You can do so by cleaning out your
_plugfolder right on the file system, or use the document picker, filter onplug.jsand delete every single document that’s in the_plugfolder that way. - If you somehow end up in a state where SilverBullet doesn’t load properly, have a look at Troubleshooting for hints on what to try to fix it.
2.2.0
This is a dot release primarily because due to changes in how IndexedDB databases are named, a fully resync and reindex of your space will happen on all your devices. I’m sorry for the inconvenience, we try to limit how often this is required. If you’d like to clean up unnecessary databases afterwards you can run the Client: Clean command (once) afterwards.
- Client Encryption: when using a untrusted device (e.g. a public computer), enable this option when logging in (only supported with built-in Authentication) to encrypt all locally stored data (at a performance penalty).
- Lua fixes, making Space Lua more compatible with Lua 5.4 (most courtesy of of Matouš Jan Fialka):
- Fix length (
#operator) features - Add
rawgetandrawequal - Allow
..to also concatenate strings and numbers - Make truthiness more Lua compatible
- Align arithmetic model with standard Lua
- Add
hugeconstant andtypetomath.*API - Add
loadfunction - Support %u in os.date
- Pass on status code differently when using
http.request
- Fix length (
- More video embeds in standard library (courtesy of Andy Costanza):
- New
widget.htmlBlockandwidget.markdownBlockconvenience APIs for creating block widgets (that take the full width of the screen rather than being inlined) - The ^Library/Std/APIs/DOM API now supports embedded widgets and markdown
- The markdown renderer now renders ${“````````````````````````````````````````b-code``````````````````````````````````````````````````````````````````````````````````````
- Atomic upgrades with ````````````````````````d ``````````````````````````````````````````````````tps://github.com/silverbulletmd/silverbullet/pull/1634))
- Added ````````` Clean````````````````````````ll redundant IndexedDB databases (ones the client is not using)
- Very basic Prometheus metrics (see Install/Configuration > Metrics)
- Fix: bottom search bar dark mode styling (by numan)
- Fix: navigation with auto links (by MrMugame)
- Fix: ```````````````````````` `````````````````````````````````
2.1.8
- New ^Library/Std/APIs/Virtual Page API, internally used by:
- Some fixes in `````````````````ng
- Default table renderer now renders ``````````````````````````````````````clickable: ${queryfrom index.tag “page” limit 3 select {ref=ref, lastModified=lastModified}}
- Fix: render TOC correctly when header itself contains a link (by Oleksandr Kuvshynov)
- Fix: read-only pages are now never saved back to your space (could happen, e.g. with tasks on tag pages)
- Fix: Table of Contents widget works again
- Fix: Poor behavior when multiple pages are delete in sequence (by Oleksandr Kuvshynov)
- Lua:
- Setting a table value to `````````````````````````````` so it no longer appears in ````````````````````````````````````````````````````````````````````````````````````````
2.1.7
- Restructure of the `````````````````````` added some more (self) documentation. See ^Library/Std as an entry point.
- Re-added ```````````` event that was removed in 2.1
- When the clipboard API is used in Safari, will now give a proper error (Safari restriction) by (Noah Stanley)
- Full text search results now show full page path
- Space folders now support symlinks again (regression from 2.1)
- Lua: fixes in arithmetic model (by Matouš Jan Fialka)
- Lua: Removed unary plus from grammar (wasn’t actually supported) (by Matouš Jan Fialka)
- Bugfix: auth and service worker caching fixes
- Bugfix: docker health check failed when SB_URL_PREFIX was used
- Bugfix: infinite item index loop in obscure cases
2.1.4 - 2.1.6
- Fixed broken auth in Safari
- Renamed the inconstently named ``````````````````````````````````arch.enabled````````````````````````````````````````````````````````````````````````````````
- Last opened (for pages) and last run (for commands) timestamps are now kept persistently between client loads (and tabs)
- Fixed docker user and group creation issues
- Removed ```````````ed````````````````````````ng for ```````````````````````````````````````````````````````verSearch)
- Server: HTTP Gzip compression is now enabled for sensible content types
- Nicer syntax to query tag objects from the index: `````````````````````````````````````````````````````implemented here: ^Library/Std/APIs/Tag)
- Hidden files and folders (starting with ``````````````````````````````````````````` without a file extension (those were not support anyway)
2.1.2
This is a major architectural overhaul compared to 2.0. Please — as always — make sure you regularly backup your space files to avoid any data loss. Nothing should happen, but better be safe than sorry!
- All new server written in Go (previously written using Deno). Uses significantly less memory and is significantly smaller in size.
- Docker base image is now based on Alpine (previously Ubuntu), further reducing memory and disk space usage.
- Significant engine re-architecture: see Architecture and Sync, now lives in the service worker and parallelizes sync. Once upgrading a full resync will need to happen. Documents are no longer synced by default (you can enable this via config, see Sync).
- More configuration options for what to index (see ^Library/Std/Config under the ``````````````````````````````````````````````````````````````````````````````````````` Some useful ones:
- `````ig.set(“index.search.enabled”, false)```````````````````````````````````````````````es on processing and storage if you don’t use it)
- `````ig.set(“index.paragraph.all”, false)``````````````````````````````````````````````s. This is also somewhat wasteful if you don’t query these.
- Disable ability to rename pages in read-only mode (by Jelenkee)
- Improved docker build + health check (by Zef)
- Added `````````s.tagItem```````````````````````````za](https://github.com/silverbulletmd/silverbullet/commit/6d4f964a6e2a4f7dae04aa7558defcaa9f1f1a86))
- Support links in table queryable objects (by Alex Dobin)
- Refactor of document editors (by MrMugame)
- Command to toggle markdown syntax rendering (by aphymi)
- Fix transclusions not being indexed as links (by MrMugame)
- Render links inside frontmatter code as clickable anchors (by Andy Constanza)
- New ```````_PUSH```````````````````ents to push their browser JS logs to the server so they’re visible there.
- Hot reloading plugs has been disabled because it caused some nasty race condition. To explicitly reload plugs without restarting the client, use the ````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
2.0.0
- We’re now live!
For previous versions, see the v1 CHANGELOG