Smallweb 0.27
by Achille Lacoin
3 min read
Hey, it's been a while! I've did not spent a lot of time developping Smallweb in the last few months, but I've been using it a ton! I think it's a great sign of the project's maturity.
Host you own registry in smallweb
The biggest pain point of smallweb compared to platforms like Val Town has always been the lack of easy way to share your code between apps (as they only have read access to their own folder), or between smallweb instances. The main issue has always been the dynamic nature of smallweb, where apps the code of an app can be changed at any time, without any stability guarantees.
I've found a really elegant solution to this problem, by leveraging the isomorphic-git library, which is a pure Javascript implementation of Git. Pairing it with smallweb opens up a lot of possibilities, and I intend to explore them in the future.
The first app I've built on top of it is a registry app. You can install it by creating a single file in your smallweb instance:
// $SMALLWEB_DIR/esm/main.ts
import { Registry } from "jsr:@smallweb/registry";
const { SMALLWEB_DIR } = Deno.env.toObject();
const registry = new Registry({
root: SMALLWEB_DIR
})
export default registry
The registry needs read permissions to your whole smallweb directory, so will give it admin rights from our global config file:
{
"domain": "example.com",
"apps": {
"esm": {
"admin": true
}
}
}
Now, let's say I want to publish a new app to the registry. The only thing I need to do is to init a git repository in the app folder, and create new commits:
mkdir my-app && cd my-app
cat <<EOF > main.ts
export default {
fetch: () => "Hello, world!"
}
EOF
# initialize the git repository
git init -b main
# create a commit (c02c547 is the commit short hash)
git add . && git commit -m "Initial commit"
And just like that, my app is now available in the registry (ex: main.ts
is available https://esm.example.com/my-app@c02c547/main.ts
).
I can then immediately reference it from another app (even from another smallweb instance!)
// $SMALLWEB_DIR/hello-world-copy/main.ts
export { default } from "https://esm.example.com/my-app@c02c547/main.ts";
Using this pattern, you can easily deploy multiple versions of the same app, and each deployment will have their own data folder.
I love to be able to implement such a huge feature completely in userland, without having to change the smallweb core. It really shows the modularity of smallweb's design.
In the future, I plan to use similar patterns to implement continuous deployment workflows.
Introducing the smallweb REPL
When you run smallweb
without any arguments, it will now start a interactive REPL, with every of your app represented as a command.
It is especially useful on mobile, where you can use a terminal client like Termius to easily interact with your apps on the go.
Deno 2.4 is now the minimum supported version
Deno 2.4 comes with my most wanted feature ever: text
and bytes
imports!
import message from "./hello.txt" with { type: "text" };
import bytes from "./hello.txt" with { type: "bytes" };
console.log("Message:", message);
// Message: Hello, Deno!
console.log("Bytes:", bytes);
// Bytes: Uint8Array(12) [
// 72, 101, 108, 108, 111,
// 44, 32, 68, 101, 110,
// 111, 33
// ]
I plan to use the feature a ton to distribute static assets from the import graph in smallweb, so I decided to make it the minimum supported version.
Plugins are now custom commands
You should now store them in .smallweb/commands/
instead of .smallweb/plugins
. Otherwise, there behavior stays the same, you can still use them with smallweb <custom-command>
.