My website ships zero JavaScript. I wrote its generator in Rust.
The page you're reading sends no executable JavaScript to your browser. The only <script> tag on it carries JSON-LD — structured data for search engines, not code that runs. I build the whole site with a single Rust program of my own: it turns Markdown into HTML, inlines the CSS into every page, and writes a folder of static files. No framework, no client-side runtime, no build step you can't read in one sitting. This is how I did it, and what I gave up to get there.
Why not just use a framework?
Because I didn't need one, and every framework I tried made the site heavier than the content it carried.
A personal site is a handful of pages that change slowly. Most static-site generators answer that with a plugin system, a theme layer, a JavaScript hydration step, and a node_modules folder bigger than everything I'd ever publish. I'd spend more time learning the tool's opinions than writing.
So I treated it the way I treat everything else: keep it minimal, keep it deterministic. The generator is about 1,400 lines of Rust in a single file — built with AI as an ally, the way I build everything, but mine to understand end to end. I can hold all of it in my head. When the build does something I don't like, I open the file and fix it — there's no layer underneath that I don't control.
The dependencies are four crates, and that's deliberate:
[dependencies]
comrak = "0.52.0" # Markdown -> HTML
maud = "0.27.0" # HTML, checked at compile time
serde = "1.0" # config parsing
toml = "1.1" # the config format
maud is the part I'd recommend to anyone. The HTML is written as Rust, so a malformed tag is a compile error, not a bug you find in production. The site can't ship broken markup, because broken markup won't build.
What does "zero JavaScript" actually mean here?
It means nothing on the page executes. I checked the output, not just my intentions: there are no .js files in the build, no <script src>, no inline event handlers. The only scripts are <script type="application/ld+json"> blocks, and that type is data — the browser parses it for search engines and never runs it.
That isn't dogma for its own sake. It's what falls out of the constraints I actually care about:
- Privacy. No JavaScript means no analytics, no cookies, no fingerprinting, nothing phoning home. Your visit is between you and the page. The contact form is the only thing that ever sends data anywhere, and only when you press the button.
- Speed. There's no bundle to download, parse, and execute before you can read. The HTML is the page.
- Longevity. Plain HTML and CSS will render in ten years. A JavaScript framework from ten years ago often won't even install today.
How is the CSS handled without a stylesheet request?
It's inlined into every page at build time. Each HTML file carries its own <style> block, so there's no separate, render-blocking stylesheet request — the browser gets one self-contained document and paints it immediately.
The design itself doesn't live in the generator. Colors, type, and spacing are CSS custom properties (--tk-*) in a token file that the whole brand shares; the build reads those tokens and folds them into each page. I can restyle the entire site by editing tokens, and I never duplicate a hex code. A full page, CSS and all, lands around 30 KB before compression. The fonts are self-hosted woff2 — no call to a font CDN that would watch who's reading.
What did I give up?
Real things. I won't pretend otherwise.
- No dynamic anything. No comments, no search box, no live widgets. If I ever truly need one, I'd have to add it deliberately — and I'd think hard before breaking the zero-JS rule.
- I maintain the generator. When I want a feature, I write it. That's a cost. It's also the point: I learned more building this than I would have configuring someone else's tool.
- It's mine to debug. There's no Stack Overflow answer for my generator. There's just the file, and the fact that it's small enough to read.
For a personal site, every one of those trades went my way.
Where does it run?
The generator produces a dist/ folder of static files, and that folder goes to Cloudflare Pages as a direct upload — Cloudflare just serves bytes, it never runs my Rust. On top of the static files sit a strict Content-Security-Policy and security headers, an RSS feed so you can follow along without an algorithm in the middle, and a JSON-LD entity graph so search engines know who's behind the site.
That last part matters to me beyond SEO: this site is the hub. The platforms point here; I don't rent my audience from anyone's feed. Owning the output end to end — down to the generator that builds it — is the same instinct that produced Kremis. Build the thing yourself, keep it small, and you get to understand it completely.
Would I do it again?
Yes — for a site like this. Few pages, slow to change, mine to own.
If you need a store, a dashboard, or anything genuinely interactive, don't copy this. Reach for a framework and move on with your life. But if your site is words and links, you almost certainly don't need a megabyte of JavaScript to show them. You need HTML, a little CSS, and the willingness to keep it minimal.
Minimal but powerful. It's the whole point.
Drafted with AI as an ally and edited by hand — the ideas, the architecture, and the technical claims are mine. The code examples are real; you can see what I build at github.com/TyKolt.