How This Site Is Built
This site is intentionally boring. The goal is a small, durable personal website that’s easy to maintain for years, easy to write in, and easy to deploy. No runtime backend, no database, no request-time rendering: just content and a predictable build.
Core decisions
Static generation with Jekyll
The site is built with Jekyll, a Ruby-based static site generator.
- Content is written in Markdown.
- Templates are simple HTML + LiquidJS.
- Output is plain static files (fast, cacheable, low attack surface).
Posts are written as dated Markdown entries (with front matter) and become URLs like:
/posts/YYYY/MM/DD/title/
The exact URL shape is controlled by a permalink setting in the site configuration.
Markdown-first authoring (with HTML allowed)
Everything important is Markdown:
- Posts: dated writing (the blog)
- Pages: evergreen content (about, links, quotes, etc.)
- “Books” / notes (optional): longer-lived reading notes or summaries
Markdown keeps content portable and diff-friendly, and Jekyll’s Markdown engine allows inline HTML when needed.
Content management: Decap CMS + Git Gateway
To keep editing convenient without adding a backend, the CMS is Decap CMS (Git-based). Content edits happen via /admin/ and are committed into the repository.
Authentication + Git operations are handled by Netlify Identity + Git Gateway:
- Netlify Identity: login / user management
- Git Gateway: lets the CMS write to your Git repo without requiring the editor to have an account on your Git hosting provider
The CMS is configured with a YAML file that defines collections (posts, pages, etc.), their fields (title, date, tags), and where media uploads go.
Deployment: Netlify
The site deploys to Netlify:
- A build command runs Jekyll via Bundler
- The output is a static site directory
- A Netlify config file defines the build settings and ensures the admin UI routes correctly
Because the output is static, deploys are quick and rollbacks are easy.
Navigation & taxonomy
To avoid complexity, the site uses one taxonomy: Tags.
Implementation detail: one built-in front matter field is treated as the site’s “tags” list, and tag archives are generated automatically.
Automatic tag pages
Tag pages like:
/tags/engineering/
are generated via the jekyll-archives plugin and rendered with a simple tag-archive layout.
Feeds, SEO, and other “boring but important” features
The plugin set is small and standard:
jekyll-feed: generates/feed.xmlfor RSS readersjekyll-sitemap: generates/sitemap.xmlfor crawlersjekyll-archives: generates tag archive pages
This keeps the build predictable and avoids custom generators.
Local development
Local dev runs in Docker for consistency:
- A compose file runs
jekyll serve - A Makefile (or a few documented commands) wraps common tasks like “serve” and “rebuild”
This avoids “works on my machine” Ruby version issues.
Styling philosophy
Styling is CSS-only and content-first:
- Clean typography and a readable measure
- Strong defaults for code blocks (developer blog)
- Minimal UI chrome (header/footer don’t compete with content)
One CSS file does almost all the work. The emphasis is on good defaults: typography, spacing, links, and code blocks.
Summary
The stack is deliberately minimal:
- Jekyll for static generation
- Markdown for content
- Decap CMS for editing
- Netlify + Git Gateway for deployment + auth
The result: a site that’s fast, maintainable, and easy to publish to—without a runtime backend or a JS framework.
If you want to recreate this site (human- or AI-generated)
Here’s a concise “spec” you can hand to another AI (or use as a checklist) to generate an equivalent repository.
Site goals
- A personal site + blog with excellent readability and fast load times
- No client-side framework requirement (plain HTML/CSS output)
- Write content in Markdown with front matter
- Simple navigation: home, posts index, about, links, quotes, tag index
Content model
- Posts: dated Markdown entries with title, date, and tags
- Pages: Markdown pages for about/links/quotes (and optional books/notes)
- Tags: one tag list per post, plus auto-generated tag archive pages
URL structure
- Posts at
/posts/YYYY/MM/DD/slug/ - Tag archives at
/tags/<tag>/ - A posts index at
/posts/and a tag index at/tags/
Templates & layouts
- A default layout with header + footer and a centered, readable content column
- A post layout that renders title/date/tags and the post body
- List layouts for posts and tag archives
Styling requirements (CSS-only)
- Comfortable type scale, line height, and measure (roughly 65–75 characters)
- Good defaults for headings, lists, blockquotes, and links
- Code blocks styled for developer writing (monospace, padding, horizontal scroll)
- Mobile-first spacing and typography
Editing workflow (optional but recommended)
- Decap CMS served at
/admin/ - Netlify Identity + Git Gateway for authentication and Git writes
- CMS collections for posts and pages, including media uploads
Deployment & dev environment
- Netlify deploy with a single build command (Bundler + Jekyll)
- Local development via Docker to avoid Ruby version drift
- A couple of convenience commands (Makefile optional)
Resources
- Jekyll: Jekyll docs
- Decap CMS: Decap CMS docs
- Netlify Identity: Netlify Identity docs
- Git Gateway: Git Gateway docs
- LiquidJS: LiquidJS docs