Smallweb 0.15

by Achille Lacoin

5 min read

Hey there! I'm happy to announce the release of Smallweb 0.15.

I never had as much users asking when the next release would be, which is quite motivating. I hope this release will live up to your expectations!

Also, if you're interested in a cloud version of smallweb, please consider adding your email to the smallweb cloud waitlist.

You can upgrade to the latest version by running the smallweb upgrade command.

TLDR

  • you should move your smallweb config from ~/.config/smallweb/config.json to $SMALLWEB_DIR/.smallweb/config.json
  • you can customize the smallweb directory by setting the SMALLWEB_DIR env variable
  • apps now only have write access to the data folder in their app dir
  • authentication is now handled from deno, and not from the smallweb config
  • the global env variables are now set in $SMALLWEB_DIR/.env, and not in the smallweb config
  • you now need to add a --cron flag to the smallweb up command to run the crons

Smallweb directory as the source of truth

I talked about my previous smallweb setup in a previous post. In this setup, smallweb is deployed on a VPS, and I sync the app to my local machine using mutagen.

Even though this setup worked quite well, I found it to be a bit cumbersome. The main issue I had was that I had to connect to the VPS each time I wanted to run an app cli entrypoint with the smallweb run command.

It always felt a bit weird to me. If the smallweb dir is synced to my local machine using mutagen, why can't I run the cli entrypoints locally?

Starting from this release, the cli entrypoints can be run from anywhere, as long as the smallweb dir is synced to your local machine. This is because the smallweb dir is now the source of truth for the whole smallweb state.

  • smallweb open can be use to open an app url in your browser, even if the app is running on a remote server
  • smallweb run [app] can be used wherever your are, as long as the smallweb dir is synced to your local machine

Updated permissions

Apps now only have write access to the data subdir (relatively ot the app root). They still have read access to the whole app dir.

This change will allow me to distinguish between updates made by the app, and updates made by the user, in order to strategically restart the app only when necessary (currently the app is restarted on each request).

Rethinking authentication

In the previous version of smallweb, I introduced a private field in the app config. This field was used to protect the app behind an authentication layer.

I realized that this was not the right approach. Auth requirements are often more complex, and using a static field in the app config was not enough.

Moreover, this means that the auth logic could not be used outside of smallweb, when I want most smallweb app to be able to run through deno serve.

So instead of using a private field in your app config, you should now directly wrap you app in the lastlogin middleware:

import { lastlogin } from "jsr:@pomdtr/lastlogin";

export default {
  fetch: lastlogin((req: Request) => {
    const email = req.headers.get("X-Lastlogin-Email");
    return new Response(`Hello, ${email}!`);
  }),
};

The lastlogin middleware include a bunch of options, you can check them out in the package doc.

Removal of smallweb:* entrypoints

I tried to move as much logic as possible to userspace. This means that the smallweb:* entrypoints are no longer supported.

  • smallweb:static can be replaced by jsr:@smallweb/file-server
  • smallweb:api can be replaced by jsr:@smallweb/api
  • smallweb:wevdav can be replaced by jsr:@smallweb/webdav

Automatic compilation of markdown files

The smallweb file server will automatically compile markdown files to html.

This means that you can just create a folder of markdown files, and go to https://<folder>.<domain>/<file>.md to see the compiled html.

This uses the @deno/gfm package behind the scenes.

New env variables

Smallweb now automatically inject some env variables in your app:

  • SMALLWEB_DIR: the path to the smallweb dir
  • SMALLWEB_DOMAIN: the domain of the smallweb instance
  • SMALLWEB_APP_NAME: the name of the app
  • SMALLWEB_APP_URL: the url of the app

You can easily access it them from your app code using Deno.env.

const {
    SMALLWEB_DIR,
    SMALLWEB_DOMAIN,
    SMALLWEB_APP_NAME,
    SMALLWEB_APP_URL,
} = Deno.env.toObject();

Global .env file

Instead of configuring the global environments variable from the smallweb config, you should now use a .env file at the root of the smallweb dir.

# ~/smallweb/.env
MY_SECRET=123

open function for cli entrypoints

Cli entrypoints used to share the same restrictions as the rest of the app. However, having the ability to open a url in the user's browser is quite necessary for cli entrypoints.

You can now easily achieve it by using the open function from the @smallweb/open package:

import { open } from "@smallweb/open";

export default {
    async run() {
        // open can only used from the `run` method
        await open("https://smallweb.run");
    }
}

Update to crons

Since smallweb can now run from multiple servers, you now need to specify which server should trigger the crons.

You can do this by adding the --cron flag to the smallweb up command:

# run both the http server and the crons
smallweb up --cron

Or, if you want to dedicate a server to crons, you can use the smallweb cron up command:

# run only the crons
smallweb cron up

Update to smallweb logs

Logs are now saved to $XDG_CACHE_DIR/smallweb/logs. You can view them as they are generated using the smallweb logs command:

smallweb logs

You can filter the logs by app using the --app flag:

smallweb logs --app my-app

The smallweb logs will only show the logs from the smallweb instance the command is run from. If you want to see the logs from another instance, you can pair it with the ssh command:

ssh <remote-server> smallweb logs

What's next?

Moving from a cgi-bin model to a serverless model

Currently each request is sandboxed in it's own subprocess. This is fine for simple apis, but it quickly becomes a bottleneck for more complex apps, with multiple consecutive requests.

I a future version of smallweb, apps will "stay warm" between requests for a few seconds, allowing for faster responses.

Web IDE based on vscode

Now that I have found a neat model for admin apps, I plan to create a vscode integration entirely in userspace!

I'm taking inspiration from Membrane here, please check them out if you haven't already.

Smallweb Cloud

Owning your own VPS, or buying your own domain should not be a requirement to run smallweb apps. I'm working on a cloud version of smallweb, inspired by blot.im.

With a single command, your local smallweb dir will be available at https://<app>.<username>.smallweb.live. You'll then be able to access the app logs and metrics from a cloud dashboard at https://smallweb.live.

Please consider adding your email to the smallweb cloud waitlist if you're interested!