SITE-TEMPLATE
← Back

Deploying a blog to the edge

This entire site is a single JavaScript file running on Cloudflare Workers. There is no bundler, no framework, and no node_modules directory in the deployed artefact — just an ES module with a fetch handler and a D1 binding.

Why a single file

A blog is a small amount of logic wrapped around a small amount of data. Splitting that across a dozen modules and a build pipeline adds latency to every change without adding capability. Keeping it in one file means:

  • the whole system fits in your head
  • wrangler deploy is the only build step
  • cold starts stay under a millisecond
  • the HTML, CSS and SQL live next to the logic that produces them

The request path

Every request runs a lazy bootstrap, resolves the session cookie, and then hits the router. Rendering is a tagged template that escapes interpolated values by default:

const page = html`<h1>${post.title}</h1>`;

Because html escapes anything it interpolates, injecting markup through a post title is not possible — the escape is the default and raw() is the explicit opt-out.

Storage

D1 is SQLite at the edge. Three tables carry the whole application: users, posts and sessions. Reads are prepared statements bound with positional parameters, so nothing is ever concatenated into SQL.

The result is a blog you can read end to end in an afternoon and deploy in about four seconds.