Sabino Lab
All posts

How this site is built

Vinext on Cloudflare Workers, Markdown compiled at build time, a D1 database for the interactive bits, and very little JavaScript in the browser.

2 min read Engineering

This site is small, but I wanted it to be fast, cheap to run, and fully mine: the posts, the comments and the newsletter list all live in places I control.

The stack

Piece Choice
Framework vinext, the Next.js API on Vite
Runtime Cloudflare Workers, via OpenAI Sites
Database Cloudflare D1 (SQLite) with Drizzle ORM
Styling Tailwind CSS v4
Content Markdown files in the repo

Markdown, compiled ahead of time

Posts are plain .md files with front matter. A small Vite plugin turns each file into a JavaScript module during the build, so the server never parses Markdown or highlights code when you load a page:

export function markdownContent(): Plugin {
  return {
    name: "sabinolab:markdown-content",
    enforce: "pre",
    async transform(code, id) {
      if (!id.endsWith(".md")) return null;
      const doc = await renderMarkdown(code, id, contentDir);
      return { code: `export default ${JSON.stringify(doc)};`, map: null };
    },
  };
}

That module includes the rendered HTML, a table of contents, the reading time, and plain text for search.

Syntax highlighting

Code blocks are highlighted by Shiki at build time too, so there's no highlighting library in the browser.

The interactive parts

Comments, the contact form and the newsletter all post plain HTML forms to route handlers. They work without JavaScript, and everything is stored in D1:

CREATE TABLE subscribers (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  email TEXT NOT NULL UNIQUE,
  status TEXT NOT NULL DEFAULT 'pending',
  token TEXT NOT NULL UNIQUE
);

Owning the subscriber list means I can export it as CSV at any time and switch email providers without asking anyone.

Projects from GitHub

The projects page asks the GitHub API for my public repositories, caches the answer in D1 for an hour, and serves the last good copy if GitHub is unreachable. A small overrides file lets me feature a project, rename it or add screenshots without touching code.

Comments

No comments yet. Start the conversation!

Leave a comment

Comments are reviewed before they appear.