Recently I made a URL shortener web App jsr:@indirect/short that is using JSR only (i.e. npm free) and could be setup on the Deno Delpoy Playground with just a one-liner:
1export { default } from 'jsr:@indirect/short@1'
or in command-line:
1deno serve -N --unstable-kv jsr:@indirect/short@1
I wondered how much effort it would take to make it deployable to Cloudflare Workers as well. Since used Hono as an underlay, which is platform-agnostic to begin with, this should be pretty easy to do, with only a few
Caveats #
WebAssembly #
The hashing function used here is FNV-1a from jsr:@std/crypto built by its WASM code. Unfortunately, it's not supported out of the box by Cloudflare Workers:
Cloudflare Workers deals with wasm differently than other runtimes. Specifically, you can't initialise an instance from a string like above, it has to be a separate modules that's imported.1
To work around this, replacing it internally with the pure JS version from npm @sindresorhus/fnv1a instead.
KV Bindings #
Unlike the Deno KV, which could be freely accessed via a global reference, the Cloudflare KV bindings have to be acquired from the routing context. The official solution from Hono is to use the built-in context storage middleware, which uses AsyncLocalStorage underneath enabled via nodejs_als
:
1# wrangler.toml
2
3compatibility_flags = [ "nodejs_als" ]
Using .jsx / .tsx from JSR #
The support for .jsx
/ .tsx
on JSR is half-baked at the moment2. Therefore, using it on a platform other than Deno Deploy requires additional manual tweak, mainly to adjust the import path that remains after JSR installation:
1# wrangler.toml
2
3[build]
4command = "node build.mjs"
1// build.mjs
2
3import * as esbuild from 'esbuild';
4
5import { esbuild_plugin } from '@indirect/short/hotfix';
6
7await esbuild.build({
8 entryPoints: [ 'main.js' ],
9 bundle: true,
10 format: 'esm',
11 platform: 'node',
12 target: [ 'node20', 'es2022' ],
13 plugins: [ esbuild_plugin ],
14 outfile: 'bin.js',
15});
Putting all of the above together, I've created a template repo for easy setup. Feel free to give it a try.
Compare #
Deno Deploy
In retrospect, it has been such a smooth experience to take TypeScript, JSR, and Deno Deploy as a complete package deal. However, over the years, the Deno Deploy platform has always felt like a show house, by and large.
Deno KV was announced in May 2023, with an open beta in September. To this day (Dec 2024), it is still behind the switch of --unstable-kv
.
The deploy feedback issue repo has barely received any attention. To me, it's unclear where Deno Deploy as a platform is headed.
Cloudflare
They have a wide product lineup to experiment with, and it can take you quite far even with the free-tier offering.
I wish it could expand better support for JSR, reduce the friction to allow dev focus more on writing code instead of manually wiring things up, i.e. the one-liner deploy through playground for import npm:
or jsr:
prefix without touching package.json
and .npmrc
at all.
It's funny that I started this project by selecting Hono (being acquired by Cloudflare) for use on Deno Deploy, with a few tweaks to deploy it back onto Cloudflare, which completing the circle.
BYOC (Bring Your Own Cloud) #
That's it: a dedicated URL shortener web App, with no tracking, privacy concerns, or risk of rug pulls. You manage your own data, usage, and deployment.
With only one-liner…ish.