Migrating SilverBullet Plugs from Deno to Node

This guide describes how to migrate a SilverBullet plug from the old Deno-based build system to the new Node/npm-based one.

Note: you can do this at your leasure, your old Deno builds should continue to work. However, newer versions of the APIs will no longer be published to JSR, just as an npm package.

What changes

Before (Deno) After (Node)
deno.jsonc with tasks and import map package.json with scripts and dependencies
deno.lock package-lock.json
deno run -A <url>/plug-compile.js npx plug-compile
jsr:@silverbulletmd/[email protected] @silverbulletmd/silverbullet from npm

What stays the same: Your .plug.yaml manifest, your .ts source files, and the @silverbulletmd/silverbullet/... import paths all remain unchanged.

Steps

1. Delete Deno files

rm deno.jsonc deno.lock

2. Create package.json

{
  "name": "silverbullet-yourplug",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "build": "npx plug-compile yourplug.plug.yaml"
  },
  "dependencies": {
    "@silverbulletmd/silverbullet": ">=2.5.3"
  }
}

Replace yourplug with your plug name matching your .plug.yaml file.

3. Create .gitignore

node_modules/
*.map

4. Install and build

npm install
npm run build

This produces yourplug.plug.js (and a .map sourcemap file) in the current directory. Use --dist <path> in the build script if you want the output elsewhere.

See the silverbullet-mermaid repository (to-node branch) for a complete example of this migration.

2 Likes

Going to be honest here, I don't like this, still have to fight the *** **** esbuild is. I'm still forced into some specific built system and I still have to hack my way around it. Bundle size also increased by +10% .... The built code actually feels worse than deno now ...

Bundle size increased? That’s very odd…

I’m open to more radical ideas around plug development. What I tried to do here is the minimal possible change to not produce much work for people.

Ok, taking back what I said on bundle size, that is actually in the "frontend", I really have no clue why tho.
I guess I'm really limit testing the build system and build systems drive me up the wall, but I would have wished that the plugin API was just available as a library and I could do something like the following

Silversearch.initPlugin({
     name: "silversearch",
     functions: {
         "search": {
             func: () => console.log("Searching!"),
             command: {
                 name: "Silversearch: Search",
                 key: "Ctrl-s"
             }
         }
    }
})

Then I could just use the build system of my choice, or none at all, meaning I would have full control for debugging purposes, could use vite features to e.g. import files as raw strings, etc. (One would also get typechecking on the manifest.)