Smallweb 0.16

by Achille Lacoin

5 min read

Hello again!

With the release of Smallweb 0.15 last week, you might have expected a bit of a break. But I've been working on some really transforming performance improvements these last few days, and I decided to release them as soon as possible.

So here we are, with Smallweb 0.16!

You can upgrade to the latest version by running the smallweb upgrade command (or smallweb upgrade 0.16.0 if you want to be specific).

TLDR

  • smallweb can now reuse the same deno process for multiple requests
  • symlinks can now be used as apps
  • you can now create apps from templates using the smallweb create --template flag
  • smallweb now supports serving a index.md file as your website root
  • plugins are now stored in $SMALLWEB_DIR/.smallweb/plugins, and can have any file extension
  • smallweb sync command to manage the mutagen sync
  • admin apps now have access to the smallweb cli
  • smallweb now has a bluesky account: @smallweb.run

New Runtime inspired by Val Town

You may have noticed that smallweb apps sometimes feel sluggish, especially web apps with many assets. This performance issue stemmed from a design choice: smallweb previously spawned a new Deno process for every request. While this approach avoided the need for a dev server or build step, it introduced significant overhead. However, hosting apps on smallweb shouldn’t come with such a steep performance penalty, so I decided to overhaul the runtime to reuse the same Deno process for multiple requests.

To ensure apps restart only when necessary, I introduced a watcher process in the smallweb evaluation server. This process monitors changes in the app directory. When it detects a change, the current worker is replaced by a new process. Apps also automatically stop after 10 seconds of inactivity to free up resources.

To distinguish between user updates (which should trigger a restart) and app updates (which shouldn’t), I added a dedicated data folder in the app directory in the latest version. Apps now have write access only to this folder, while retaining read access to the rest of the directory.

In my testing, these changes have been so transformative that I don’t feel the need to include performance benchmarks in this post. Just update smallweb—you’ll notice the difference immediately!

A big thanks to Max McDonnell for inspiring this change. His work on the new Val Town runtime provided valuable insights and saved me a lot of time during implementation.

Symlinks are now correctly resolved in the smallweb dir. It means that you can create an alias for your app, and it will be available at an additional domain.

# create a gh symlink to the github app
ln -s ./github gh

Now both github.smallweb.run and gh.smallweb.run will point to the same app.

Add support for index.md

If your static app contains an index.md file (but no index.html), it will be automatically compiled to html and served at the root of the app. This is useful for mini apps that only contain a single markdown file.

--template flag for smallweb create

You can now specify a template when creating a new app:

# clone the smallweb homepage as smallweb-homepage
smallweb create --template=github.com/pomdtr/smallweb.run/www smallweb-homepage

You can get the list of available providers in go-getter readme.

If you create a template repository on github, make sure to add a smallweb-template tag to it!

Reworked Plugin API

Smallweb used to have the same plugin system as git: you just needed to add smallweb- prefixed binary somewhere in your path, and it would be picked up by smallweb.

I had two issues with this approach:

  • plugins were not synced with the smallweb dir
  • since they could not have file extensions, syntax highlighting was tricky in some editors.

From now on, plugins will be stored at $SMALLWEB_DIR/.smallweb/plugins, now longer need to include the smallweb- prefix, and can have any file extension.

$ tree ~/smallweb/.smallweb
~/smallweb/.smallweb
├── config.json
└── plugins
    ├── pull.sh
    └── push.sh

If you want your plugins to be only available for a specific host, you can put it in $XDG_DATA_DIR/smallweb/plugins instead.

smallweb sync command

Smallweb shines when you have live syncing between your local machine and your server using mutagen. But the recommended command to achieve it was a bit intimidating:

mutagen sync create --name=smallweb-run --ignore=node_modules,.DS_Store --ignore-vcs --mode=two-way-resolved \
  smallweb.run:/home/smallweb.run/smallweb ~/smallweb

Instead, if you have smallweb installed in both the local and remote machine, you can now run:

# smallweb sync create [ssh-remote]
smallweb sync create smallweb.run

Smallweb will automatically infer the smallweb dir from the remote machine, and create the mutagen sync for you.

There are also a bunch of other commands allowing to monitor or terminate the sync. You can even register the sync process as a service using smallweb sync service register.

Behind the scenes, every smallweb sync command maps to a single mutagen command.

Admin apps now have access to the cli

Admin apps now have access to the smallweb cli (but plugins are disabled).

// ~/smallweb/changelog/main.ts
export default {
  fetch: () => {
    const { SMALLWEB_EXEC_PATH, SMALLWEB_ADMIN } = Deno.env.toObject();

    if (!SMALLWEB_ADMIN) {
        throw new Error("This app is not an admin app");
    }

    const command = new Deno.Command(SMALLWEB_EXEC_PATH, ["changelog"]);
    const output = await command.output();
    const body = new TextDecoder().decode(output.success ? output.stdout : output.stderr);

    return new Response(body, {
        status: output.success ? 200 : 500,
        headers: {
            "content-type": "text/plain",
        },
    });
  }
}

You can use this mechanism to the smallweb cli from the browser:

cli demo

Make sure to setup proper authentication first!

New bluesky account for smallweb

I've been in an honeymoon phase with bluesky for the past few days, and I decided to move the smallweb account there. Bluesky is far more open to automatisation than twitter, and I think it's a better fit for smallweb.

If you have a bluesky account, please follow @smallweb.run. And if you feel like it, you can also follow me at @pomdtr.me.

What's next?

VS Code integration

I'm writing this blog post from VS Code, running in smallweb!

vscode demo

It's still need some polishing before distributing it through JSR, but it is promising. You can try it at https://vscode-demo.smallweb.run.

With the new runtime, it already runs like a charm!

Smallweb Cloud

I now have a clear plan on how to build smallweb cloud, and it might come sooner than you think.

If you're interested in the idea of a managed smallweb instance, please signup at https://cloud.smallweb.run.