Jekyll is a static site generator. You write content in Markdown, define layouts in HTML, and Jekyll compiles everything into a folder of plain files ready to serve from any host — no database, no PHP, no server process running 24/7.
This guide covers the fundamentals: what Jekyll does, how it’s structured, and when it’s the right choice.
What Jekyll Actually Does
Jekyll takes a folder of source files and builds a _site/ folder of flat HTML. That’s the entire job.
flowchart LR
A[source/\\nMarkdown & Layouts] --> B{Jekyll Engine}
B --> C[_site/\\nGenerated HTML]
style B fill:#3b82f6,stroke:#1d4ed8,color:#fff
style A fill:#4b5563,stroke:#374151,color:#fff
style C fill:#10b981,stroke:#047857,color:#fff
During that build, Jekyll processes Liquid template syntax ({{ page.title }}, {% for post in site.posts %}), converts Markdown to HTML, and applies your layouts.
The output in _site/ has no dependencies. Drop it on Cloudflare Pages, GitHub Pages, Netlify, an S3 bucket, an nginx server — it works everywhere.
Core Concepts
Layouts
Layouts live in _layouts/. They define the outer shell of your pages — the <head>, navigation, footer.
<!-- _layouts/default.html -->
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }}</title>
</head>
<body>
{% include nav.html %}
{{ content }}
{% include footer.html %}
</body>
</html>
{{ content }} is where the page’s own content gets injected. Every page or post declares which layout to use in its front matter:
---
layout: default
title: About Me
---
Front Matter
Front matter is the YAML block between --- delimiters at the top of any file. Jekyll reads it as metadata you can reference in templates.
---
layout: post
title: "My First Post"
date: 2026-03-05
categories: [Tutorial, Jekyll]
---
You can define any variable you want — author, thumbnail, featured: true — and use it in your templates as {{ page.author }}, {{ page.thumbnail }}, etc.
Posts
Posts live in _posts/ and follow the naming convention YYYY-MM-DD-title.md. Jekyll parses the date from the filename and makes it available as {{ post.date }}.
<!-- _posts/2026-03-05-jekyll-101.md -->
---
layout: post
title: "Jekyll 101"
---
Your post content in Markdown here.
You loop over posts in templates like this:
{% for post in site.posts %}
<article>
<h2><a href="{{ post.url }}">{{ post.title }}</a></h2>
<time>{{ post.date | date: "%B %d, %Y" }}</time>
</article>
{% endfor %}
Includes
Reusable HTML snippets live in _includes/. Pull them in anywhere with {% include filename.html %}.
_includes/
nav.html
footer.html
cta-box.html
Collections
Collections extend the post model to any content type — team members, projects, products, documentation pages. Define them in _config.yml:
collections:
projects:
output: true
permalink: /work/:name/
Then create files in _projects/my-project.md and loop over them with {% for project in site.projects %}.
Data Files
_data/ holds YAML, JSON, or CSV files you can reference in templates without building a full collection.
# _data/team.yml
- name: Alice
role: Designer
- name: Bob
role: Developer
{% for person in site.data.team %}
<p>{{ person.name }} — {{ person.role }}</p>
{% endfor %}
_config.yml
The site’s configuration file. Defines the site title, URL, plugin list, and any global variables you want available as {{ site.variable_name }} across all templates.
title: "My Site"
url: "https://mysite.com"
description: "A personal blog about design and code."
plugins:
- jekyll-seo-tag
- jekyll-sitemap
# Custom variables
twitter_handle: "@myhandle"
How a Build Works Step by Step
- Jekyll reads
_config.yml - Loads all plugins
- Reads
_data/files intosite.data - Reads posts from
_posts/intosite.posts - Reads collections into
site.collection_name - Processes each page: evaluates Liquid, applies layout, converts Markdown
- Copies
assets/as-is - Writes everything to
_site/
The result is deterministic. Same input always produces the same output.
When Jekyll Is the Right Choice
Jekyll is a good fit when:
- Content changes infrequently — blogs, portfolios, documentation, landing pages
- Performance matters — static files on a CDN are as fast as it gets
- Security is a concern — no server process to exploit, no database to inject
- You want portability — pure files, any host, no lock-in
But the biggest long-term advantages often go unmentioned:
Total Version Control. Because everything is a text file, your entire website lives in a Git repository like GitHub. If you make a mistake, you can roll back to any previous version in seconds.
Automated Deployments. When combined with Cloudflare Pages or GitHub Pages, your workflow becomes invisible. You make a commit (either locally or directly through the GitHub web interface), and the CDN automatically builds and deploys your changes worldwide. No FTP, no manual uploads.
Zero Maintenance, Infinite Peace of Mind. Without databases to upgrade, PHP versions to manage, or security plugins to monitor, the ongoing maintenance drops to absolute zero. This translates to massive time and cost savings. Over the long run, you spend your time actually creating content instead of keeping a server alive.
It’s not the right fit when:
- You need user-generated content or real-time data
- Non-technical editors need to publish without any setup
- You have thousands of pages with complex relationships (build times become a factor)
The Part Nobody Mentions
The learning curve isn’t in understanding Jekyll’s concepts — those are straightforward. The friction comes from:
Liquid syntax. It’s readable but unfamiliar. Filters like {{ post.date | date: "%Y" }}, conditionals, loop offsets — these take time to get comfortable with.
Want to dig deeper into the code? Check our guide on Mastering Advanced Liquid Techniques.
Theme architecture. Open-source Jekyll themes vary wildly in structure. Some use Gem-based themes (layouts live inside the gem, not your repo). Others bundle everything in the repo. Knowing how to override without forking the whole theme is non-obvious at first.
CSS compilation. Themes that use Sass require understanding the _sass/ folder structure and variable overrides. A small change to a color can require tracing through three layers of imports.
If you’re comfortable with HTML and CSS but want to skip the Liquid and build scaffolding, a visual builder — like Jekyll Builder — handles the template layer so you can focus on design and content.
Further Reading
- Official Jekyll documentation — comprehensive reference
- Deploy Jekyll to Cloudflare Pages — step-by-step deployment guide
- Best Jekyll Themes in 2026 — curated starting points for new projects
Want to skip the Liquid learning curve entirely? Jekyll Builder gives you a visual canvas that generates standard Jekyll templates — no Liquid required to get started.
Next on your learning path: Static Sites vs WordPress: Which should you choose?