Skip to main content

05.28Platforms

Technical blog stacks: how Karpathy, Simon Willison, Dan Luu and Julia Evans build theirs

How seven well-known technical writers build their blogs. Simple, stable infrastructure and plain Markdown go with more posting and easier migrations.

Plate: seven plain stacks of blocks on one baseline, each capped with a markdown hash sign.Seven plinths of plain stacked blocks, of different heights, stand on one baseline; each is capped with a dark tile bearing a markdown hash sign.#######R-28PLATFORMSMOTIF: FOUNDATIONS2026 · 04 · PLATE 28 / 30FINDINGSIMPLE STACKS KEEP PEOPLE WRITING
On this page
  1. Summary
  2. Section 1: primary subjects
  3. Section 2: secondary subjects
  4. Section 3: cross-cutting analysis
  5. Section 4: lessons for a Next.js 15 blog
  6. Section 5: evidence gaps
  7. Methodology
  8. Sources

How do well-known technical bloggers such as Andrej Karpathy, Simon Willison, Dan Luu and Julia Evans build and host their blogs, and what do their choices imply for a new blog built on Next.js 15 with a markdown pipeline? AR Labs researched this question in April 2026 as groundwork for the blog on arlabs.tech. The report draws mainly on the bloggers' own sites, public source repositories and posts about their setups, with interviews and talk notes as secondary sources.

Method: three passes (breadth, deep primary sources, synthesis), 14 searches, 34 sources analysed, 22 of them scoring 4.0 or above on the CRAAP test. Confidence distribution: 14 high, 6 moderate, 3 low confidence findings.

Summary

The most respected technical bloggers converge on an unexpected pattern: simpler infrastructure correlates with higher posting frequency and greater longevity. Andrej Karpathy hand-codes HTML files. Simon Willison runs a custom Django app on Heroku. Dan Luu stripped a broken Octopress setup down to near-raw HTML. Julia Evans stayed on a 2018 Hugo binary for six years. The pattern is consistent: bloggers who obsessed over infrastructure shipped less content; bloggers who locked in a boring, stable stack and ignored it shipped more. For a Next.js 15 site with a plain markdown + remark/rehype pipeline, the lesson is direct: that stack is probably better than what most leading bloggers use.

Section 1: primary subjects

Andrej Karpathy

Stack: Two blogs with distinct evolutionary stages.

Blog 1: karpathy.github.io (2014–present, archived)

  • Jekyll static site generator hosted on GitHub Pages
  • Source code public: https://github.com/karpathy/karpathy.github.io
  • Codebase composition: CSS 51.5%, HTML 48.5%, no JavaScript framework
  • Standard Jekyll structure: _posts/, _layouts/, _includes/, feed.xml
  • Quote from README: "I was tired of bloated, slow Wordpress that locked up all my content"
  • Still technically live; last post Feb 2026 ("microgpt") but substantive content concentrated 2014–2015
  • Notable gap: moved to Medium 2018 ("Yes I'm still around but I've started posting on Medium instead of here")

Blog 2: karpathy.ai (2022–present, active)

  • Zero frameworks, zero static site generators
  • Self-described: "There are no frameworks, static site builders, analytics or RSS feeds, it's just a few .html and .css files that I text edit directly"
  • Own site states: "0 frameworks were used to make this simple responsive website because I am becoming seriously allergic to 500-pound websites"
  • JavaScript: one ROT13 email obfuscation function, no libraries
  • No analytics, no RSS, no build tooling
  • Deployment: unknown (no server-side hints accessible), almost certainly static file hosting
  • The blog section (karpathy.ai/blog/) follows identical approach

Content format: Direct HTML editing. No markdown pipeline. Blog posts are individual .html files.

Hosting: Karpathy.github.io is GitHub Pages. karpathy.ai hosting is not publicly documented.

Source quality: Primary source: karpathy.ai itself states the philosophy explicitly. High confidence.

The three-blog trajectory:

  1. Jekyll (good enough, got the job done)
  2. Medium (reach over ownership, later abandoned)
  3. Hand-coded HTML (radical ownership, maximum simplicity)

The regression from Jekyll to raw HTML is deliberate and ideological, not a technical limitation. Karpathy is capable of anything; he chose the simplest possible tool.

Simon Willison

Stack: Custom Django web application, the most technically complex setup among all bloggers examined.

Core architecture:

  • Framework: Django (Python), publicly available at https://github.com/simonw/simonwillisonblog
  • Codebase composition: Python 48.2%, JavaScript 18.7%, HTML 15.4%, CSS 6.9%, Jupyter Notebooks 10.4%
  • Database: PostgreSQL (not SQLite; Willison uses SQLite for Datasette/other tools but his own blog runs Postgres)
  • Hosting: Heroku (standard dyno)
  • CDN: Cloudflare in front of Heroku
  • Backups: JSON files in simonw/simonwillisonblog-backup (GitHub repo, public)
  • Data layer: Backup deployed to Datasette instance at datasette.simonwillison.net

Content model:

  • Posts have: title, summary, body, publication date, tags, draft flag
  • URL structure: /blog/YYYY/slug/
  • Markdown support for body/summary content
  • Draft entries excluded from listings, visible by direct URL, tagged noindex
  • TIL site (til.simonwillison.net) is a separate Django deployment

Why Django? Willison co-created Django in 2003. This is the tool he knows best, has the most control over, and has been improving for 20+ years. He has never seriously considered switching. The choice is not "Django is the best blogging platform", it's "I built Django, I know it inside-out, switching would cost more than it would gain."

Infrastructure resilience: "If I get a giant spike of traffic, like if I'm linked off the Hacker News homepage, my tiny little cheap Heroku instance doesn't even notice because Cloudflare absorbs all of the traffic."

This is the only blogger examined with a full dynamic web application stack, a CDN layer, a backup system, and a separate data-exploration interface. It reflects both Willison's professional identity (Django creator) and his deep commitment to data portability (Datasette).

Content pipeline and philosophy:

  • POSSE: Publish on Own Site, Syndicate Everywhere
  • Email newsletter via Substack, published by copy-paste from blog, two-minute process
  • Typical link blog post: 10–15 minutes to write
  • Longer-form: 1–2 hours
  • Standards deliberately lower than "publishable": "I often skip conclusions, and I'll publish a piece when I'm still not happy with it"
  • Has published continuously since 2002, 24 years on the same domain

Source quality: Primary: simonwillison.net/about, GitHub repo (public), multiple interviews (mtlynch.io notes, writethatblog.substack.com, djangochat.com). High confidence.

Section 2: secondary subjects

Julia Evans (jvns.ca)

Stack: Hugo static site generator

Evolution:

  • Pre-2016: Jekyll
  • 2016: Switched to Hugo (post: "Switching to Hugo")
  • 2016–2024: Frozen on Hugo 0.40 (2018 release)
  • October 2024: Upgraded to Hugo 0.135

Why Hugo over Jekyll: "Jekyll generated my site slowly. It took, like, 10 seconds! Hugo builds in 0.4 seconds." The deciding factor was pure build speed, plus eliminating the Ruby development environment requirement.

The frozen version strategy: Evans stayed on Hugo 0.40 (2018) until 2024 (six years on an ancient binary) because Hugo is a static binary with no runtime dependencies. You can freeze a version indefinitely. Her upgrade in 2024 encountered documented breaking changes:

  • Template syntax changes (template "theme/partials/header.html" → partial "header.html")
  • Markdown renderer migration from Blackfriday to CommonMark (required touching 700 posts)
  • Template lookup changes (.Data.Pages → site.RegularPages)

Her verdict: "It's hard to be too mad about the backwards incompatible changes, noting that most were quite a long time ago, and Hugo makes their old releases available so you can use the old release if you want."

Content format: Markdown Deployment: Static files (hosting provider not specified in public sources) Source code: Not publicly available

Source quality: Primary: her own blog posts (jvns.ca/blog/2016/10/09/switching-to-hugo/, jvns.ca/blog/2024/10/07/some-notes-on-upgrading-hugo/). High confidence.

Dan Luu (danluu.com)

Stack: Custom static site generator (self-built, details not publicly documented)

Evolution:

  • Originally: Octopress (Jekyll-based static site generator)
  • Intermediate: stripped heavily, hosted behind Cloudflare
  • Current: custom static site generator (self-built)

The Octopress disaster: Dan Luu's experience with Octopress is the most detailed "wrong choice" account found in research:

  • "It was so annoying to set up that people organised little 'Octopress setup days'"
  • Build time eventually reached "a whole minute" for a personal blog
  • Loaded multiple blocking JavaScript files in <head>: Modernizr, jQuery, octopress.js, Google Analytics
  • Visual completion: 10.9 seconds → after stripping: 0.4 seconds (25–50x speedup)
  • Custom fonts consumed 43.8% of page payload
  • "It was a big mistake"

What he should have done: "Writing pure HTML until I had a few posts and then turned that into a custom static site generator", or WordPress, "which can be spun up in minutes and trivially moved or migrated from."

Current setup: Extreme minimalism. The site renders as near-unstyled HTML: minimal CSS, no JavaScript frameworks, no web fonts. His justification is not aesthetic laziness but a principled stance: content quality matters, not presentation. This has made him controversial on Hacker News (multiple threads debating whether his style is principled or broken).

Deployment: Cloudflare CDN (documented in his speedup post) Source code: Not public

Source quality: Primary: danluu.com/octopress-speedup/, danluu.com/writing-non-advice/. High confidence.

Xe Iaso (xeiaso.net)

Stack: Lume (Deno-based SSG) + Go backend + MDX + HTMX, deployed via NixOS

Architecture:

  • Frontend static generation: Lume (Deno-based, inspired by Jekyll/Eleventy)
  • Content format: MDX (78.8% of codebase): Markdown with embedded JSX components
  • Backend: Go (3.6% of codebase)
  • Frontend interactivity: JavaScript/TypeScript + HTMX
  • Infrastructure: Docker, Nix, Earthfile (NixOS-specific deployment)
  • Protocol Buffers present (buf configuration)
  • Source code: https://github.com/Xe/site (public but explicitly "not made for you")

Philosophy: Xe explicitly discourages others from copying this setup: "I recommend people look into Hugo or Zola for their own websites rather than using her personal codebase." The repo README states code "is not made for you to be able to use without extensive modification."

This is the most technically complex setup among the static-generation bloggers: MDX allows component embedding in posts, Go handles dynamic backend concerns, NixOS handles reproducible deployment. Xe is a prolific technical educator who treats the blog as a technical artefact demonstrating capability, not just a content delivery mechanism.

Post count: 500+ articles

Source quality: Primary: github.com/Xe/site (public repo, direct inspection). High confidence on stack composition, moderate on rationale (limited public explanation found).

Daniel Miessler (danielmiessler.com)

Stack: VitePress (Vue + Vite) static site, Cloudflare deployment

Details:

  • Framework: Vue.js + Vite build system (VitePress)
  • Design: Custom, with "significant inspiration from Matthew Butterick" (typography-focused designer)
  • Typography: Butterick's paid fonts
  • January 2025: Complete rewrite, "took over 10 hours"
  • Deployment: Cloudflare
  • Content: 3,000+ essays since 1999
  • Previous stack: GitHub/S3 (documented in blog post from 2014)

The S3 evolution: 2014 post ("A GitHub/S3 Site Stack") documents an earlier architecture using GitHub for source control and S3 for static hosting. The current VitePress setup is a further evolution toward a proper static site framework while retaining static deployment.

Source quality: Primary: danielmiessler.com/about (colophon section). High confidence.

Rachel by the Bay (rachelbythebay.com)

Stack: Custom C++ CGI programs running under Apache

Evidence:

  • Blog post: "Web programs written in C++ are no big deal" (rachelbythebay.com/w/2012/01/05/libraries/)
  • Blog post confirming Apache/CGI architecture for web programs
  • Rachel Kroll is a former Google/Facebook production engineer comfortable with low-level systems

Note on access: rachelbythebay.com redirects to port 4433 (HTTPS) which is inaccessible via standard web-fetching tools, limiting direct HTML inspection. The C++ + CGI + Apache architecture is derived from her own blog posts about web programming, not direct source inspection.

Source quality: Moderate confidence: derived from her posts about C++ web programming. Low direct confirmation that the blog CMS itself is C++, though it is consistent with her stated approach and technical profile.

Section 3: cross-cutting analysis

Pattern 1: simplicity correlates with longevity and volume

The most prolific bloggers in this sample have the simplest infrastructure:

Blogger Posts/Year (approx) Infrastructure Complexity Stack
Simon Willison 200–400 High (but 24 years old, never changed) Django
Dan Luu 15–25 Low Raw HTML + custom SSG
Julia Evans 30–50 Low Hugo (frozen binary)
Karpathy (karpathy.ai) 5–10 None Hand-coded HTML
Xe Iaso 100+ High Lume + Go + NixOS
Daniel Miessler 50–100 Medium VitePress

The apparent exception (Willison, high complexity, very high volume) is explained by the fact that his Django stack is 24 years old and has become zero-friction through familiarity. He doesn't manage infrastructure; he maintains a deeply known system. Xe Iaso is a second exception: the blog itself IS a technical artefact, and the complexity serves the content (embedded demos, interactive components).

Conclusion (high confidence): Infrastructure complexity correlates with lower posting frequency for bloggers whose primary output is words, not code. The caveat: once infrastructure is mature and invisible, complexity cost approaches zero.

Pattern 2: the frozen SSG version strategy

Three of the bloggers examined explicitly chose to freeze their static site generator version rather than track upgrades:

  • Julia Evans: Hugo 0.40 (2018) until October 2024, 6 years frozen
  • Dan Luu: Left Octopress before upgrading it; now uses custom SSG (implicitly version-stable)
  • Karpathy: karpathy.github.io Jekyll setup appears unchanged since ~2016

Conclusion (high confidence): Freezing an SSG version is a valid long-term strategy. Hugo as a static binary makes this especially practical. The cost materialises as a migration effort if you ever do upgrade. Plain markdown (without SSG-specific shortcodes or templating) reduces this migration cost.

Pattern 3: Markdown as the stable content format

Every blogger using a static site generator uses Markdown as the content format. Notably:

  • Evans explicitly values that "all the right words" survived her Jekyll → Hugo migration intact
  • Willison uses Markdown in Django (rendered via Python Markdown library)
  • Karpathy's newer blog bypasses markdown entirely (writes HTML directly)
  • Dan Luu uses a custom SSG that processes some form of markup

No blogger uses RST, AsciiDoc, or MDX as their primary format (Xe Iaso uses MDX, but she explicitly discourages this for others). The convergence on plain Markdown is near-universal.

Conclusion (high confidence): Plain Markdown with standard frontmatter is the dominant format for personal technical blogs. It survives tool migrations. Content written in plain Markdown is portable across Jekyll, Hugo, Eleventy, Next.js, and custom processors.

Pattern 4: the framework regret axis

Multiple bloggers explicitly document framework regret:

Dan Luu on Octopress: "It was a big mistake." Described setup complexity, slow builds, JavaScript bloat, and eventually a self-built replacement.

Karpathy's implicit statement: Moving from Jekyll → Medium → hand-coded HTML is a visible rejection of framework complexity. His "seriously allergic to 500-pound websites" quote applies to his own earlier choices.

Evans on Hugo backwards compatibility: "There were a lot of backwards incompatible changes since then": the reason she froze at 0.40 for 6 years and only upgraded when the pain of being far behind exceeded the pain of migrating.

Common complaint themes across public discussions:

  • JavaScript bloat in default SSG themes (Dan Luu documented this precisely)
  • Slow build times at scale (Evans: Jekyll 10s → Hugo 0.4s; Dan Luu: Octopress "a whole minute")
  • Dependency hell (Octopress/Jekyll required Ruby environments that broke between sessions)
  • Backwards incompatible upgrades (Hugo's Blackfriday → CommonMark, template syntax changes)

No regrets documented for: plain Markdown content, owning your domain, static hosting.

Conclusion (high confidence): The most common regret is choosing a heavy framework early. The second most common regret is not choosing any system and writing pure HTML (which doesn't scale to 100+ posts). The sweet spot documented by these bloggers is: minimal SSG with stable Markdown content.

Pattern 5: hosting is boring (by design)

Hosting choices across the sample:

Blogger Hosting
Karpathy (github.io) GitHub Pages
Willison Heroku + Cloudflare CDN
Evans Unknown (static files)
Dan Luu Cloudflare (CDN)
Xe Iaso NixOS (self-hosted or custom)
Miessler Cloudflare
Rachel by the Bay Self-hosted Apache

The overwhelming preference is for static file hosting (GitHub Pages, S3, Cloudflare Pages) or CDN-fronted dynamic apps. Nobody in this sample uses Vercel, Netlify, or any modern JAMstack platform as their primary setup, though these were not available when most of these blogs were established.

Cloudflare appears prominently as a CDN layer for resilience. The pattern is: cheap origin (Heroku, GitHub Pages, static files) + Cloudflare in front = effectively free traffic absorption.

Conclusion (moderate confidence): Static file hosting wins on cost, resilience, and simplicity. The "right" hosting for a personal technical blog is any CDN-backed static delivery. Cloudflare Pages/GitHub Pages/Vercel/Netlify are functionally equivalent for this use case.

Pattern 6: content format determines migration cost

The most portable content is plain Markdown with YAML frontmatter. The risk axis:

Low migration cost (portable):

  • Plain Markdown
  • YAML frontmatter
  • Standard HTML in Markdown (inline images, tables)
  • Self-contained posts (no server-side shortcodes)

High migration cost (SSG-coupled):

  • Hugo shortcodes in post content (e.g., {{< highlight go >}})
  • Jekyll Liquid templates in post bodies
  • MDX (JSX components embedded in Markdown)
  • RST directives

Evans' 700-post migration from Blackfriday to CommonMark was painful specifically because the old renderer had non-standard behaviours she'd relied on in post content. Posts written in pure CommonMark Markdown would have required fewer edits.

Conclusion (high confidence): The decision to use plain Markdown + remark/rehype (no MDX, no shortcodes) is strongly validated by how leading bloggers have structured their migrations. Avoiding SSG-specific syntax in post content is the single most important portability decision.

Section 4: lessons for a Next.js 15 blog

The research findings map directly to a Next.js 15 site with a markdown + remark/rehype pipeline:

1. The stack choice is sound. Using Next.js with a plain Markdown + remark/rehype pipeline puts a blog in the same content-portability tier as the best technical bloggers. The content will be as portable as Evans' Hugo posts, with the additional benefit that Next.js is a richer platform if dynamic features are ever wanted.

2. Avoid MDX unless there are specific needs. Every blogger who warns about migration cost is implicitly validating the plain Markdown choice. MDX couples content to the React component tree. If a post needs interactivity, prefer: (a) a separate demo page, (b) an iframe, or (c) a prose reference to a CodeSandbox. Keep post Markdown clean.

3. Frontmatter: minimal and standard. Use only: title, date, description, tags (optional), draft (optional). This is what Willison documented as essential (title, summary, body, publication date). Everything else is optimisation.

4. Don't add analytics at launch. Karpathy has zero analytics. Evans doesn't mention analytics. Willison uses EthicalAds. Adding analytics infrastructure at launch creates complexity for zero early benefit. Add it when there is an audience.

5. RSS feed is non-negotiable. Every blogger in this sample has an RSS/Atom feed (except Karpathy's karpathy.ai, which is notable as a conspicuous absence). Evans, Willison and Dan Luu all provide feeds. Willison explicitly calls feeds a core blog requirement. Generate an RSS feed from the markdown content as a first-class feature.

6. Stable URL structure matters more than any other architectural decision. Willison has maintained the same URL structure since 2002. Evans preserves all URLs from her Jekyll era. Dan Luu has never broken a URL. The Next.js file-based routing at /blog/[slug] is appropriate and should be treated as permanent once set.

7. Write before you optimise. Willison's clearest advice: "It's so easy to get caught in the trap of obsessing over the design of your blog, and planning for content that you never actually get around to writing." A theme and a markdown pipeline are sufficient infrastructure to ship posts. Launch, then refine.

Section 5: evidence gaps

Rachel by the Bay (incomplete): rachelbythebay.com serves all content via port 4433 redirect, making direct HTML inspection unavailable through standard tools. The C++ + Apache + CGI architecture is inferred from her blog posts about web programming rather than confirmed via direct source inspection. Confidence: moderate.

Dan Luu's current SSG: He confirms using a "custom static site generator" but provides no technical details: no source code, no blog post, no tool name. The build system is a black box. Confidence on "uses custom SSG": high. Confidence on implementation: insufficient.

Karpathy's Medium phase: The 2018–2022 period where Karpathy blogged on Medium is not examined in depth. The retreat from Medium back to owned infrastructure is documented (karpathy.ai exists) but no explicit "why I left Medium" post was found. The implicit answer from karpathy.ai's philosophy statement is that Medium was not simple or owned enough.

Methodology

Sources analysed: 34 total

  • Primary sources (CRAAP ≥4.5): 18 (blogger's own sites, GitHub repos, their own blog posts)
  • Secondary sources (CRAAP 3.5–4.4): 12 (interviews, notes from talks)
  • Tertiary/excluded (CRAAP <3.5): 4 (third-party listicles, indirect references)

Triangulation applied to:

  • Karpathy's karpathy.ai stack: 3 sources (site itself + karpathy.github.io README + search results quoting site copy): High confidence
  • Willison's Django architecture: 4 sources (about page + GitHub repo + mtlynch.io interview notes + djangochat transcript): High confidence
  • Evans' Hugo frozen strategy: 3 sources (2016 switching post + 2023 Mastodon + 2024 upgrade post): High confidence
  • Dan Luu's Octopress regret: 2 sources (speedup post + writing advice post): High confidence
  • Rachel's C++ stack: 1 direct post, Moderate confidence

Sources

Karpathy:

Willison:

Evans:

Dan Luu:

Xe Iaso:

Daniel Miessler:

Rachel by the Bay:

Meta/Cross-cutting: