Jekyll theme: where the build and layout break
A ready-made theme is almost always assembled for a specific version of the generator and a set of plugins, so the very first bundle exec jekyll build after installation often fails on dependency incompatibility: the theme pulls in a plugin that requires a different major branch, while the Gemfile is already pinned to a different set.
The symptom is that the site build passes locally but falls apart on CI, because a fresh version of the gem gets pulled in there.
The second class of failures is template conflict. The theme brings its own _layouts and _includes, and when you add your own pages, Liquid inheritance breaks: layout: default from the theme overrides yours, and include pulls in someone else's partial.
The layout doesn't fall apart right away — first the wrapper disappears, then the grid shifts on inner pages.
The third source is plugins. Some themes are designed for building via GitHub Pages with a limited whitelist, and any plugin outside the list is silently ignored: Sass doesn't compile, pagination doesn't appear, and the output stays empty with no explicit error.
Separately, responsive layout comes up: the theme was laid out for a fixed content width, and long tables or code blocks overflow the viewport. Plus asset versions aren't busted, and the browser keeps the old CSS after edits.
Let's break down how each of these failures gets resolved — from pinning dependencies to overriding templates without editing the theme's files.
What a tuned theme delivers: speed and stability
A Jekyll site build degrades imperceptibly: first 8 seconds, then 40, then minutes for every change. The cause is almost always the same — the theme drags along the entire set of plugins and template dependencies, even if a particular page uses a tenth of them.
Incremental rebuilds stop helping because any edit in the shared layout invalidates the entire cache, and you wait for a full cycle for the sake of one line of text.
Customizing the theme solves this at the structural level, not cosmetically. We separate layouts by purpose, move heavy computations out of templates into includable data, disable unused plugins, and pin dependency versions.
Build time drops predictably — a typical project speeds up severalfold, and hot rebuild returns to seconds because it no longer depends on the entire template tree.
The second effect is that an entire class of output errors disappears.
A broken Liquid filter, an unescaped character in a heading, a broken link in navigation, duplicate meta tags — all of this shows up not at build time but on the live site, and gets caught only through complaints.
When templates are brought to a uniform form and covered by checks, such defects are cut off before publication: the build fails with a clear error instead of silently corrupting the page.
Separately — stability across environments. The local machine, the staging environment, and production build the same result because versions are pinned and the configuration differs only by parameter overrides.
This eliminates the classic "it works on my machine but not on the server" and makes rolling back to a previous state a routine operation rather than an investigation.
In sum, a tuned theme is a predictable publishing pipeline: an edit reaches the site in seconds, the output is identical everywhere, and errors are visible at the build stage rather than in production. Next we'll break down what such tuning consists of.
Approaches to customization: comparing the options
Customizing a Jekyll theme almost always comes down to one question: what to do when you need to deviate from the author's design.
There are three fundamentally different ways — editing the theme's source files directly, overriding individual files on top of it, or building your own layer of styling.
The choice determines what happens on the next theme update and how much time maintenance will take six months from now.
| Option | When it fits | Limitations |
|---|---|---|
| Editing the theme's source files | A one-off project, we won't update the theme anymore | An update overwrites the edits; the change history is mixed with someone else's |
| Overriding files | You need to change the layout, styles, or template partially | Works only for files that Jekyll picks up by priority |
| Your own layer on top of the theme | Long-term maintenance, regular updates, your own design | Requires discipline: the more layers, the more important the structure |
Editing the source files gives a quick result and full control, but every theme update turns into a manual merge. Overriding is a compromise: we put our own versions of files into the project, and Jekyll gives them priority while taking the rest from the theme.
This works for styles, some templates, and configuration, but it won't save you if the data structure the theme relies on changes.
Your own layer is the most sustainable path for projects that live for years. The theme remains an immutable dependency, and all our code sits separately: our own layouts, our own styles, our own includable blocks.
A theme update then doesn't break the design, and adding a new section doesn't require digging into someone else's files. Let's break down how to choose the option for your case and what to consider during the migration.
Theme setup and customization stages
We start with an audit: we look at what's already in the theme and what will have to be rewritten. We check the directory structure, the set of templates, the connected plugins, and how the site is built on the current Jekyll branch.
The output is a theme map: which files are responsible for rendering, where markup is duplicated, which dependencies carry extra weight.
- Theme audit. We go through the source files, collections, layouts, and includes, and record the customization points and risks: hardcoded paths, a bloated
_config.yml, plugins without support. We verify the behavior against what is stated in the task. - Structure design. We decide what to change in the templates, what to move into data files, and what to handle with a separate plugin. We layer the styles so that edits don't break neighboring blocks.
- Setting up templates and styles. We rewrite layouts and includes for the required markup, bring typography and the grid to a consistent look, and remove duplicated markup in favor of reusable components.
- Connecting plugins. We add only what solves the task: collection generation, image processing, sitemap, code highlighting. We check each plugin for compatibility with the current branch and for build speed.
- Verification. We build the site locally, run the pages for broken links, check the output at different resolutions and the correctness of rolling back to the previous theme version. Separately, we look at the build time before and after the edits.
- Handover. We deliver the configured theme with a description of the structure, instructions for local building, and a list of the changes made, so the team can develop it without us.
This order keeps customization predictable: every change is tied to a specific file and verified before handover. If theme limitations come up during the audit, we mention them right away, not after the build.
What the client receives: configurations and documentation
Work on a Jekyll theme does not end with "fixed styles" but with a set of artifacts that allow the project to be developed without the person who made the edits. Below is exactly what remains with the client after customization.
- Configuration files —
_config.ymlwith extracted parameters: base URL, collections, template defaults, build settings. Editing content and structure does not require digging into code. - Template schema — a map of layouts, includes, and data files: which template is responsible for what, where the entry point is, which blocks are reused. With it, a new developer gets oriented in an hour, not a week.
- Style system — theme variables (colors, typography, spacing) in one place, styles split into layers, and a rule for how to add new components without breaking existing ones.
- Access and role policies — who can change what: content, templates, build configuration. Separation of rights eliminates edits "outside the process."
- Dependency update policy — frequency, procedure for checking plugin and generator compatibility, rollback point to the previous build.
- Local setup instructions — how to spin up the project, build and verify changes before publication, which checks are mandatory before deployment.
- Plugin and extension catalog — what is connected, why, and what constraints it imposes on the site structure.
- Theme changelog — what changed and when, to distinguish author edits from updates.
This set is enough for the client's team to maintain the site on their own, while we step in on a targeted basis — for complex enhancements. Describe your task: we will come back with an estimate and a plan for your project.
Case study: how a tuned theme made builds three times faster
The project is a corporate documentation site built on Jekyll: about 4,000 pages, three languages, daily content edits from several authors.
The original theme was taken ready-made and "tuned" on top of it: dozens of overrides in _sass, heavy template inheritance chains, plugins, each of which re-read the entire _posts directory during the build phase.
A full build took 11–14 minutes, an incremental one about 3 minutes, and any author who fixed a single line waited longer for the result than it took to write the fix.
What it was like before customization
Measurements on a clean clone showed where the time was going: more than half went to re-traversing collections and generating tag pages, another quarter to compiling styles due to nested @import without splitting into critical and deferred parts.
Templates pulled data through site.pages in its entirety instead of targeted selections via where, so each page re-iterated the whole list from scratch.
What was changed
The style layer was rewritten: a flat partials structure, unified theme variables, output of a single compiled file instead of a cascade of overrides.
Plugins were replaced with built-in collections with explicit output: true and limited selections, heavy computations were moved into a separate step that runs once and is cached between builds. Templates were switched to targeted data access, and duplicate includes were removed.
| Metric | Before | After |
|---|---|---|
| Full build | 11–14 min | 3.5–4 min |
| Incremental build | ~3 min | 20–30 s |
| Compiled CSS | 480 KB | 180 KB |
| Number of override templates | 60+ | 12 |
What this achieved
An author sees the result of an edit in tens of seconds instead of minutes — the "changed, checked, pushed" cycle is no longer a bottleneck.
The build on the server fits within the deployment window, and rolling back to the previous release remains available because artifacts are built reproducibly.
At the same time, the theme remains customizable: a new block or section is added by editing a single partial, rather than searching for the right override among dozens.
How is editing a theme different from overriding it?
Editing a theme means changing files inside the theme itself: templates, styles, partials.
Overriding means the original stays untouched, and a layer appears alongside it that replaces it: your own template with the same name, an additional stylesheet loaded on top, your own set of data instead of the built-in one. The difference is not cosmetic — it determines what happens on the next theme update.
Editing looks faster: open the template you need, tweak the markup, add a style. The problem shows up later, when a new version of the theme is released with fixes and new features.
You can't update — any update will overwrite your changes, and there's nothing left to compare them against the original with: it's unclear what was yours and what came from the theme.
Six months later, no one on the team remembers why a non-standard line appeared in a particular partial, and they're afraid to touch it.
Overriding is built on the principle that the theme stays unchanged and updatable, while all your customizations live in a separate layer. A template with the same name in your directory takes priority over the theme — and the original remains intact.
Styles are loaded after the theme, so they override its rules without editing the source files. Logic is moved into separate pluggable modules rather than embedded in someone else's code.
The strategy is chosen based on the time horizon. If the theme is a one-off and there are no plans to update it, editing is acceptable and cheaper.
If the site will live for years and you'll be updating the theme, overriding pays for itself on the very first update: it goes through without conflicts, and your customizations stay in place.
In practice, a mixed approach is more often taken — overriding selectively where the theme will change, and editing directly in places that definitely won't be touched.
At the start, we document this boundary: what is overridden, what is changed inside the theme, and why. It costs a couple of hours and removes the main pain of maintenance — the inability to update without the risk of breaking the site.
Common technical concerns when working with a theme
A theme is just a set of templates, styles, and configuration, so all concerns boil down to three things: whether the build will break after an update, whether generation will hit the site size limit, and whether the theme will pull in extra weight into the finished page.
Will updating the theme overwrite our template edits?
If the edits live directly in the theme files, an update will overwrite them. That's why we move customizations into a separate layer: our own child templates, style overrides, and site configuration — then an update pulls in the new version while your changes stay on top.
Before updating, we snapshot the current state in version control, build the site on a copy, and compare the result — a rollback takes minutes.
Compatibility of plugins and third-party libraries
Plugins fall into two categories: those that run at build time and those that are loaded into the finished page.
We check the former for compatibility with the current generator branch and dependency versions, and the latter for conflicts with each other: two libraries for the same widget often break one another.
Every plugin adds time to the build, so we keep only those that provide a real function rather than duplicating built-in capabilities.
Will the site take too long to build?
Build time grows with the number of pages and plugins, not with the size of an individual page. The bottleneck is usually heavy operations on every item: image generation, code highlighting, recalculating related entries.
We speed things up in a targeted way: cache intermediate results, move one-off processing out of the build loop, and limit rebuilds to only the files that changed. On a project with several hundred pages, this brings the build back to minutes instead of tens of minutes.
What about the performance of the finished pages?
A static page is served quickly, but a theme is easy to bloat: extra fonts, unused styles, scripts loaded on every page without necessity. We build a single optimized stylesheet instead of a dozen, defer secondary scripts, and compress images at build time.
As a result, the page serves ready markup immediately, without waiting for server-side logic, and content edits don't require restarting the application.
If your concern isn't on this list, describe your situation and we'll look into it separately.
Let's discuss your theme setup task
So that theme setup doesn't turn into a guessing game, we start by breaking down the task: what kind of site it is, who uses it, which sections and page types are needed, and how content is published.
On a call, we clarify the initial data and the scope of work — after that, we come back with a plan and an estimate, without "we'll make it look nice and figure out the rest later."
What we'll go over in the discussion:
- Current state: a ready-made theme, custom-built markup, or a set of templates — this determines the scope of customization rather than a rewrite from scratch.
- Structure: which collections, post types, and pages are needed, how sections and navigation are organized, and where custom templates will be required.
- Content and publishing: who adds materials and how, whether markup support is needed, automatic builds, and preview before publishing.
- Design and styles: brand colors, typography, mobile responsiveness — what we take from the theme and what we override.
- Functionality: forms, search, integrations, analytics — what we connect out of the box and what requires a separate solution.
- Constraints and timelines: priorities, phasing, what's critical for launch, and what can be moved to a second phase.
Based on the conversation, we lock in the work plan: stages, scope of changes, approval points, and the order for verifying the result. Describe your task in whatever form is convenient — we'll come back with an estimate and a plan.







