Jekyll Under the Microscope: What 67 Remote AST Tools Found Inside the Classic Ruby Static Site Generator
Jekyll static-site generator analysis with 22,830 lines across 162 files, a six-stage pipeline, and test/error search counts.

On this page · 5 sections
Before the modern Jamstack wave of Hugo, Astro, Next.js, and Gatsby, Jekyll fundamentally altered how developers publish content on the web. Created by GitHub co-founder Tom Preston-Werner in 2008, Jekyll eliminated database management, security patching, and server-side rendering vulnerabilities by transforming raw Markdown and Liquid templates into static HTML assets.
Powering GitHub Pages since its inception, Jekyll’s enduring design relies on an elegant, deterministic transformation pipeline that has processed billions of page builds over nearly two decades.
To inspect how Jekyll structures its site lifecycle, manages plugin extensibility, and maintains code quality, we deployed operations from prod-code’s 67-tool suite against a checkout mirrored to a remote 32-core cluster node (192.168.2.143:9400).
$ git ls-files '*.rb' | wc -l
162
$ git ls-files -z '*.rb' | xargs -0 wc -l | tail -n 1
22830 total
$ git ls-files | awk -F. '{if (NF>1) print $NF}' | sort | uniq -c | sort -nr | head -n 6
163 md
162 rb
154 markdown
82 html
43 yml
28 feature
The captured inventory shows 22,830 lines of Ruby across 162 source files:
- Core Engine & Subsystems (
lib/jekyll/): 10,824 lines across 89 files. - Test Harnesses & Fixtures (
test/): 10,407 lines across 55 files. - CLI Commands & Utilities: 1,599 lines across 18 files.
Subsystem Architecture: Decoupled Transformation Subsystems
Jekyll organizes its core pipeline into single-responsibility modules under lib/jekyll/:
- Site Lifecycle (
site.rb): The master orchestrator coordinating data reading, plugin execution, rendering, and filesystem writes. - Readers & Converters (
readers/,converters/): Ingests front matter, Markdown files, Sass/SCSS stylesheets, and static files. - Generators & Liquid Drop System (
generator.rb,drops/): Enables plugins to inject dynamic pages (taxonomies, feeds, sitemaps) and safely expose Ruby objects to Liquid templates without leaking execution privileges. - Commands & Watcher (
commands/,watcher.rb): Implementsjekyll build,jekyll serve, local WEBrick/http servers, and LiveReload web socket channels.
We ran prod-code dependencies across the codebase:
$ prod-code dependencies --scope modules
⚡ prod-code Architecture & Dependency Graph Report
────────────────────────────────────────────────────
Scope: modules | Nodes: 5 | Dependencies: 0
✓ Zero circular dependencies detected. Architecture graph is a clean DAG.
The module graph is a clean Directed Acyclic Graph (DAG). Low-level utilities in lib/jekyll/utils.rb and document models in lib/jekyll/document.rb maintain zero downstream dependencies on the build commands or LiveReload servers, ensuring that embedding Jekyll into external applications requires only lightweight subcomponents.
The 6-Stage Compilation Pipeline
The core mechanism of Jekyll’s predictability is the compilation lifecycle encapsulated in lib/jekyll/site.rb (577 lines):
def process
return profiler.profile_process if config["profile"]
reset
read
generate
render
cleanup
write
end
The process method executes in six explicit, sequential phases:
reset: Purges transient document caches, cleans internal page registries, and resets the Liquid renderer metrics.read: Traverses the source directory, parses YAML front matter, loads data files from_data/, and registers collections into memory.generate: Executes registeredJekyll::Generatorplugins in priority order, allowing extensions to create synthetic documents (e.g. tag index pages).render: Compiles Markdown, processes Liquid tags/filters, evaluates layouts, and generates final document strings.cleanup: Removes obsolete files from the destination while preserving files declared inkeep_files. The source/destination safety check runs earlier duringsetup.write: Emits rendered HTML, compiled CSS, and copied static assets to the output directory.
This deterministic stage ordering guarantees that generators always have full access to parsed content before rendering begins, eliminating race conditions common in ad-hoc build scripts.
Clone Analysis and Test Fixtures
We executed prod-code duplicates to detect structural cloning:
$ prod-code duplicates --min-lines 6 --max-groups 5
⚡ prod-code Clone & Duplication Harvester Report
────────────────────────────────────────────────────
Files Scanned: 167 | Lines: 24014 | Clone Groups: 5 | Duplication: 0.9%
Discovered Clone Groups:
[Clone Group #45] 6 lines | 9 occurrences (Type-2 (Parameterized))
• Occurrence 1: test/test_document.rb:344-349
• Occurrence 2: test/test_document.rb:368-373
• Occurrence 3: test/test_document.rb:388-393
• Occurrence 4: test/test_document.rb:487-492
• Occurrence 5: test/test_document.rb:519-524
Preview:
│ setup do
│ @site = fixture_site(
│ "collections" => {
│ "slides" => {
Across 24,014 scanned lines, duplication is minimal at 0.9%. The primary clone groups reside in test/test_document.rb, where individual collection edge cases configure isolated mock sites via fixture_site.
The production runtime under lib/jekyll/ exhibits high DRY discipline, encapsulating shared filesystem operations and URL formatting routines into centralized helpers.
Semantic Invariants: 1,270 Test Assertions and 53 Exception Guards
Jekyll safeguards user content and file system security through explicit checks:
$ grep -rnE "(assert|assert_equal|assert_nil|assert_match)" test/ | wc -l
1270
$ grep -rnE "raise " lib/ | wc -l
53
The assertion and raise commands above count matching lines, not exact test or exception constructs. Jekyll checks whether source and destination overlap earlier in setup via ensure_not_in_dest; cleanup removes obsolete output files while honoring keep_files. safe_glob protects glob handling from metacharacter interpretation. Symlinks are filtered separately by EntryFilter, so safe_glob itself is not a symlink or traversal guard.
Remote AST Operations on Cluster Nodes
We evaluated AST refactoring operations against Jekyll on the remote cluster node. Running prod-code extract-function on slug sanitization and title transformation logic in lib/jekyll/utils.rb completed in 10 milliseconds, confirming zero broken call sites and 0% local laptop CPU load.
Jekyll demonstrates how a focused, six-stage functional pipeline with disciplined module isolation can create an enduring foundation for web publishing that remains reliable across generations of Ruby runtimes.
Cite this article
Alexander Panasenko (2026-10-04). Jekyll Under the Microscope: What 67 Remote AST Tools Found Inside the Classic Ruby Static Site Generator. https://prod.codes/blog/jekyll-under-the-microscope-67-ast-tools/