A long standing challenge I never managed to tackle is how to properly distribute libraries (space lua, space styles etc.) and plugs. For plugs there’s a bare bone plug manager + a config setting but… it’s not a great and very nice experience.
I’m currently working on a new approach to this problem…
Here are my work in progress notes, open to feedback. Sorry these are rough notes, I hope they make sense to people “in the know” (e.g. @Mr.Red who’s been looking into this). There’s a demo GIF at the end of the post.
Libraries are SilverBullet’s mechanism to build and distribute extensions to SilverBullet.
Libraries can consist of:
- Pages containing:
- Space Lua scripts (Lua extensions)
- Space style scripts (CSS extensions)
- Plug files (JavaScript extensions)
- Any other documents (images, PDFs, whatever)
The root of a library is a page tagged with #meta/library. This makes them eligible for updates.
Libraries become discoverable via repositories that are just pages (that can self update from a remote source) containing lists of library names with URIs to download them from.
Libraries are kept under Library/ Repositories under Repository/.
Distributed with SB itself:
Repository/Std: a “blessed” list of installable libraries that will be updated with new SB releases.Library/Std: this will have all built-in plugs asfilesas well as all existing std pages.
Frontmatter used for pages tagged with #meta/library:
- version: used for update checking
- files: for any additional files, with paths relative to the library page
Changes required core to enable this
- Load all files in space ending with .plug.js as plug, not just under
_plug/prefix
Commands
Library: Add Repo(asks URI)- Downloads under
Repo/<<name>>
- Downloads under
Library: Update Repos(fetches all#meta/repopages, reimports based onuri)Library: Remove Repo(picker, removes page)Library: Install- List all
#meta/library/remoteitems - Pick, install under
Library/<name>
- List all
Library: Update All:
Update process:- Find all
#meta/libraryitems, extract name (relative to Library/) - Look up in
#meta/library/remotefetch remote, compare versions, replace
- Find all
Library: Remove- Asks for
#meta/libraryobject to remove - Remove process:
- Remove library file
- Remove linked files
- Asks for
Repositories
Repositories are pages tagged with #meta/repo with frontmatter:
uri: for self updates
Objects tagged with #meta/library/remote, can be data blocks, or tagged items:
- Schema:
nameuri
Library
Best practices
Simple libraries can be single page artifacts. Many can be put in a single Github repo (e.g. zefhemel/silverbullet-libraries), they can also be distributed as gists. Such a repo can contain a REPO.md file which serves as the repositories linking to all the contained libraries.
More elaborate libraries (such as the built in Std), may contain a very elaborate list of additional files with a mix of plugs, documentation pages and space Lua scripts, e.g.
---
tags: meta/library
files:
- core.plug.js
- editor.plug.js
- API/Something.md
---
Plugs are generally distributed in a separate GitHub repo where the README.md page can serve also as the root of the library, typical frontmatter:
---
tags: meta/library
files:
- plug.plug.js
---
Examples:
Demo of current state

Note that this also “wraps” plugs as libraries (like SilverSearch, Mermaid), so there’s just one type of thing to install and manage. This can also replace the whole plug manager that’s currently in place.
So my rough plan is: I’ll distribute one “repository” page with SilverBullet standard distribution, with some of the more popular libraries/plugs, so those are installable with a push of a button. Then people can create their own repository pages (still need to build an installer/updater for those) with additional libraries of their own.




