Jekyll 101: A Beginner's Guide to Static Sites (2026)

What Jekyll is, how it works, and why developers choose it over WordPress. A practical introduction with no fluff.

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.

source/               →   _site/
  index.html               index.html
  _posts/                  blog/
    2026-01-01-hello.md      2026/hello/index.html
  _layouts/
    default.html
  assets/
    css/style.css          assets/css/style.css

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

  1. Jekyll reads _config.yml
  2. Loads all plugins
  3. Reads _data/ files into site.data
  4. Reads posts from _posts/ into site.posts
  5. Reads collections into site.collection_name
  6. Processes each page: evaluates Liquid, applies layout, converts Markdown
  7. Copies assets/ as-is
  8. 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

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.

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


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.

Ready to build your Jekyll site?

Start for free. No credit card required.

Start Building Free

More articles

Contact Us

Have a question or want to talk about a custom integration? Send us a message.