My Cloudflare Workers, for assorted purposes.

This is a Rush project that uses PNPM, none of these packages are published publicly.

@nchlswhttkr/hero-of-time-link Redirects requests based off a dynamic file
@nchlswhttkr/newsletter-subscription-form Manages requests to subscribe/unsubscribe from my newsletter
@nchlswhttkr/markdown-reader A reader for web-hosted markdown files
@nchlswhttkr/experimental-golang-worker Running Golang as WASM inside Cloudflare Workers
@nchlswhttkr/experimental-golang-worker Handles redirects from my old domain to various destinations
@nchlswhttkr/inject-env-loader A Webpack loader to inject environment variables as a part of builds
@nchlswhttkr/counter Having some fun with isolate persistence in Cloudflare Workers


You should make sure you can publish your workers.

  1. Create by copying the template, and replace it with your Cloudflare secrets/identifiers.

    • This should be CF_ACCOUNT_ID, CF_API_TOKEN and a CF_ZONE_ID for your default zone.
  2. Make sure you have wrangler installed.

After this, you can publish all your workers, or just a single chosen worker.

rush build
rush build --to @nchlswhttkr/newsletter-subscription-form

Rush will not rebuild a package unless it changes, or one of its dependencies changes. Changes to .gitignore'd files (for example, files with secrets) will be ignored.

You can always force a rebuild of a particular package or all packages.

rush rebuild
rush rebuild --to @nchlswhttkr/newsletter-subscription-form

New workers can be created from the template worker. Make sure to add them the rush.json config so they will be published!

./ "new-worker-name"


Link and Ezlo from The Legend of Zelda: The Minish Cap dashing forward

My personal shortcut service. For example, redirects back here.

Requests are redirected based on the links in a shortcuts.json file. The key for each shortcut must be alphanumeric.

Links will only be updated if you force a rebuild (rush rebuild --to @nchlswhttkr/hero-of-time-link).


A menu screen from Pokémon Mystery Dungeon featuring Chikorita, Totodile, and Pelipper

Manages requests to subscribe to my newsletter.

Method Path Description
GET /newsletter/subscribe/ The form to subscribe to the mailing list.
POST /newsletter/subscribe/ Subscribes a user to the mailing list, expects completed form data.
* /newsletter/subscribe/confirm Confirms a mailing list subscription, expects email and a signature.

It needs a few secrets to be provided with @nchlswhttkr/inject-env-loader.

Some values are hardcoded into this script (email sending domain, mailing list name), you'll need to change those before deploying this.

To generate a new signing secret, you can use this snippet. Changing this secret will invalidate all existing confirmation links.

Array.from(crypto.getRandomValues(new Uint8Array(16)))
  .map((n) => n.toString(16).padStart(2, "0"))


A reader for web-hosted markdown files. It parses markdown files from the web server-side and returns the response.

Takes advantage of HTTP/2 server push and preloading to get a faster paint for newer clients.

To look at a particular file, pass it in via the url parameter.


Running Golang as WASM inside Cloudflare Workers.

You will need to have TinyGo installed.


Handles redirects from my old domain to various destinations.

For reference, you can see the old Nginx config this worker replaces.


A Webpack loader to inject environment variables as a part of builds.

:exclamation: I wrote this before you were able to include secrets/environment variables with your Workers. I might remove it at a later point.

Additionally, will attempt to load environment variables from a .env file in the working directory.

For example, with the line PASSWORD=abc123 in your .env file, your build output would resemble this.

- if (password === ENV_PASSWORD) {
+ if (password === "abc123") {
    // do authenticated work


Having some fun with isolate persistence in Cloudflare Workers.

Repeated requests to will increment the counter, so long as you continue to hit the same node and the isolate is not discarded.