What building a Jekyll theme taught me

Creating a Jekyll blog theme is partly an exercise in templates and partly an exercise in restraint. A static site generator turns Markdown into fast pages, but the theme decides whether readers can scan an article, find an older post, subscribe to an RSS feed or move through the site on a phone without friction. Kilt and Code had to carry technical tutorials and personal writing without making either feel like a separate publication.

I wanted the project to be useful beyond my own posts. That meant treating the repository as a product: clear installation steps, sensible defaults, a small dependency surface and an interface another developer could adapt without reverse-engineering my taste. The goal was an open-source Jekyll blog theme that could survive years of posts, redesigns and changes in hosting.

The work began with content rather than colour. I mapped the relationships between posts, pages, projects, tags and series, then decided which data belonged in front matter and which should remain in the body. Australian readers also bring specific expectations: use colour, organisation and licence in interface copy, show dates in a familiar day-first order, and avoid implying that every reader shares one time zone.

An Australian audience may include developers in Sydney and Melbourne, remote workers in Brisbane and readers in Perth, so the result needed to work across connection speeds and schedules. A version aimed at the local market can reinforce trust with a .com.au domain and clear business details, provided registration rules are followed. The useful lesson was to localise the experience without hard-coding the entire site around one country.

Start with the content model

Content modelling saved hours later. Posts use a predictable set of fields for title, date, summary, tags and layout; pages can opt into another template; projects can carry their own links and metadata. Jekyll collections give these content types separate folders, while front matter provides the small amount of structure Liquid needs. The model stays visible in ordinary text files, which makes migrations and debugging much less mysterious.

URLs deserve early attention because changing them after publication breaks links and search results. I settled on short, readable paths and kept category information in metadata rather than burying it in directory names. Tags and series then became navigation tools instead of permanent folders. This approach also made it possible to create specialised archive pages without teaching every template about every edge case.

Building with sample posts forced decisions that an empty repository would have hidden. A featured article needs a summary. A code tutorial needs room for headings. A personal essay may need a quieter call to action. Sample posts containing C#, SQL and HTML code blocks also exposed where syntax highlighting, scrolling and spacing needed extra care. By creating representative content early, I could design the templates around real reading patterns. The sample material then became part of the documentation, giving new users a working site rather than an empty shell.

Design for reading, not screenshots

The visual design had one primary job: make long technical pages comfortable to read. A restrained measure, generous line height and clear heading rhythm mattered more than decorative flourishes. The layout uses fluid type and spacing, a narrow reading column and components that collapse cleanly on small screens. Navigation stays reachable without covering the article, and code can scroll without forcing the entire page sideways.

Mobile testing exposed more problems than desktop review. Tap targets needed more room, secondary navigation could not compete with the article body, and images needed dimensions to prevent layout shifts. Bright Australian summer conditions also made a strong light-mode contrast essential, while a dark mode based on system preferences provided a comfortable option after sunset. Reduced-motion support prevented transitions from causing discomfort for sensitive readers.

Small regional details can make an English-language site feel native without becoming gimmicky. References to a weekend barbecue, BYO coffee or a quick trip to the servo will be immediately recognisable to many Australians, so the typography and spacing should let that voice carry the page. The theme itself remains understated; the personality comes from the writing. This balance gives personal posts room to feel human while tutorials retain a practical tone.

Let Liquid stay simple and predictable

Liquid is powerful, but a theme becomes difficult to maintain when templates begin nesting loops inside conditions inside includes. I used small includes for cards, headings, pagination and metadata, then passed values with clear parameters. Each include had one responsibility and produced predictable markup. That discipline made the templates easier for a new contributor to read and for an automated check to verify.

Plugin restraint was equally important. A theme hosted with GitHub Pages works best when it relies on features available in a standard Jekyll build. I kept customisation in configuration, layouts, includes and Sass partials, and avoided making essential content depend on a plugin that might not run in the chosen environment. Anyone cloning the project can build it with the same commands used in continuous integration.

Builds fail in useful ways only when their messages are visible. I turned warnings into a signal to investigate, tested with both new and long-standing posts, and checked output rather than trusting the source alone. The trickiest defects came from missing excerpts, unusual dates and tags with no matching page. Once those cases had representative fixtures, the template logic became much easier to change without breaking an edge case.

Protect speed, access and discovery

Performance work began with measurement. I checked the generated pages with Lighthouse, inspected image weight and kept the JavaScript budget close to zero. Fonts were self-hosted and selectively loaded, images were resized and compressed, and CSS was split into the pieces readers actually need. On slower connections, those choices can matter more than a sophisticated animation. Fast pages also reduce the environmental cost of each visit.

Accessibility belongs in the build, not in a final audit. Semantic landmarks, a skip link, visible keyboard focus and sufficient colour contrast formed the baseline. Every image received useful alternative text, decorative icons were hidden from assistive technology, and interactive controls worked without a pointer. Testing with the keyboard and a screen reader exposed problems that a visual review could never show.

Discovery depends on dependable metadata and tidy output. Each page received a unique title and description, canonical links, Open Graph details and structured data where it made sense. An XML sitemap, robots file and RSS feed gave crawlers and subscribers a consistent route into the archive. Publication dates were stored predictably and rendered clearly for readers across AEST, AEDT and AWST, while the underlying data stayed suitable for international visitors.

A release checklist for the theme

A theme release is not complete when the site looks right in one browser. The repository needs a repeatable path from a clean clone to a deployable build. I kept dependency files current, automated the build and checked the generated output before publication.

Over time, that process became a practical checklist for maintenance and upgrades. It catches the changes most likely to damage a live blog, especially when content, dependencies and deployment methods move at different speeds.

The checklist also made theme maintenance feel less like guesswork. Every fix could be traced to a repeatable check, and every release could explain what had changed. That is especially valuable for an open-source project maintained in spare hours, where a clear routine protects both the project and the people depending on it.

The theme is ready to use, study and extend. Fork the repository, follow the installation guide, choose the sample content that fits, and publish your first post with the same build checks used by Kilt and Code. Use the issue tracker to report failures and document each contribution so the next maintainer can reproduce the result.