Whiskey
A dependency-aware static site generator written in Go
Whiskey
A dependency-aware static site generator written in Go.
whiskey is a modern static site generator built around dependency-aware incremental builds.
Instead of rebuilding your entire site whenever something changes, whiskey constructs a dependency graph connecting content, layouts, partials, assets, and remote sources. When a change occurs, only the pages affected by that change are rebuilt.
Unlike traditional static site generators that fetch remote content during rendering, whiskey synchronizes external sources into a persistent workspace before rendering begins. This enables deterministic builds, offline support, conditional HTTP caching, and reproducible outputs.
Why whiskey?
Most static site generators think in terms of files.
Whiskey thinks in terms of dependencies.
Markdown
│
▼
Dependency Graph
│
▼
Dirty Set
│
▼
Incremental Build
Instead of rebuilding the world, Whiskey asks:
"Which pages actually depend on what changed?"
That philosophy drives every part of the architecture.
Commands
Usage:
whiskey [command]
Available Commands:
build Build the site
check Inspect site dependencies
clean Clean generated artifacts
help Help about any command
serve Build and serve a Whiskey site
sync Synchronize remote sources
theme Manage local themes
version Version information about whiskey
Flags:
-h, --help help for whiskey
Use "whiskey [command] --help" for more information about a command.
Features
Build System
- Dependency-aware incremental builds
- Graph-driven dirty propagation
- SHA256 fingerprinting
- Configuration-aware rebuilds
- Pretty URLs
- Incremental asset pipeline
- Live reload development server
Content
- Markdown + YAML frontmatter
- Draft support
- Multi-page sites
- Collections
- Tags
- RSS feeds
- Sitemap generation
- Image shortcodes
- YouTube embeds
Templates
- Layout inheritance
- Base templates
- Partials
- Theme fallback
- Four bundled themes (
minimal,paper,terminal,noir)
Remote Content
- Remote Markdown includes
- Local includes
- Persistent materialized workspace
- Offline builds
- Conditional HTTP caching
- Workspace garbage collection
- HTML → Markdown extraction
Developer Experience
- Live reload
- Recursive file watching
- Automatic rebuilds
- Browser refresh
- Dependency graph visualization
- Remote synchronization
Architecture
Whiskey separates source synchronization from page rendering.
Markdown
│
▼
Dependency Graph
│
▼
Dirty Set Calculation
│
▼
Source Materialization
│
▼
.whiskey/workspace/
│
▼
Template Rendering
│
▼
dist/
Because rendering consumes only workspace artifacts, builds become deterministic and independent of network availability.
Key Architectural Components
The codebase is organized into highly modular packages under the internal/ directory:
- Parser (
internal/parser): Extracts YAML frontmatter metadata, expands template shortcodes (such asimageandyoutube), and compiles Markdown content into HTML. - Dependency Graph (
internal/graph): A Directed Acyclic Graph (DAG) representing layouts, partial templates, assets, pages, and includes as nodes. Edges represent dependencies (e.g.PageNode->LayoutNode). - Workspace & Materialization (
internal/source): Manages the cached HTTP local workspace under.whiskey/workspace/. It implements conditional HTTP caching (verifying ETags and Last-Modified timestamps in.whiskey/manifest.jsonbefore performing downloads). - Fingerprint Store (
internal/fingerprint): Tracks cryptographic SHA-256 hashes of all inputs in.whiskey/fingerprints.jsonto detect file updates. - Incremental Planner (
internal/planner): Decides if a layout or configuration change demands a full build, otherwise calculates the minimal set of dirty pages by analyzing the reverse path of changed inputs. - HTML Renderer (
internal/template): Loads theme HTML layouts and compiles output pages. Handles local and remote include expansion recursively.
Frontmatter
Every content Markdown file defines metadata using YAML frontmatter. The default fields are:
title: "My Page Title"
description: "A description of the page content"
date: 2026-07-13
layout: "page"
draft: false
tags:
- general
title: The display name of the page, injected into headers and<title>tags.description: A summary of the page, injected into HTML meta tags.date: Publication date used for sorting collections.layout: The template design used (e.g.page,post,index).draft: Iftrue, the page is tracked for changes but is not rendered in publishing mode (and is hidden from collections, navigation, feeds, and sitemaps).unlisted(orhidden): Iftrue, the page is rendered to HTML so it can be accessed directly by URL, but is omitted from auto-generated navigation menus, RSS feeds, sitemap XML, and collection/tag lists (perfect for custom 404 pages or secret easter egg pages!).tags: Lists taxonomies for grouping and tag lists.
Custom 404 & Unlisted Pages
- Custom 404 Page: Create
content/404.mdto define a custom error page. It is compiled intodist/404.html(anddist/404/index.html), automatically excluded from navigation, RSS feeds, and sitemaps, and served bywhiskey servewhenever a missing route is requested. - Easter Eggs & Unlisted Pages: Add
unlisted: true(orhidden: true) to frontmatter for any page you want published at a direct URL without appearing in auto-generated UI lists or navigation.
Installation
Requirements
- Go 1.25+
Clone the repository:
git clone https://github.com/sxijyoti/whiskey.git
cd whiskey
To run:
# Build:
make build
# Install:
make install
or simply,
make whiskey
# this handles build and install
Verify:
whiskey version
Quick Start
Create a new site:
site/
├── whiskey.toml
├── content/
├── layouts/
├── static/
└── themes/
# Build:
whiskey build
# Serve:
whiskey serve
# Synchronize remote sources:
whiskey sync
# Offline build:
whiskey build --offline
Project Structure
site/
├── whiskey.toml
├── content/
├── layouts/
├── static/
├── themes/
│
├── dist/
│
└── .whiskey/
├── fingerprints.json
├── manifest.json
└── workspace/
Dependency Graph
Everything inside Whiskey is represented as graph nodes.
Current node types include:
- Pages
- Layouts
- Partials
- Assets
- Remote Sources
Example:
Page
│
▼
Layout
│
▼
Base
│
▼
Partials
and
Page
│
▼
Remote Source
Whenever a node changes, Whiskey traverses the graph to determine which pages become dirty.
Incremental Builds
Every build input is fingerprinted.
Tracked inputs include:
- Markdown
- Layouts
- Partials
- Assets
- Configuration
- Remote Sources
Build flow:
Changed Node
│
▼
Dependency Graph
│
▼
Affected Pages
│
▼
Incremental Build
Only affected pages are rebuilt.
Remote Includes
Include external Markdown directly inside your content.
@include https://raw.githubusercontent.com/sxijyoti/whiskey/main/README.md
Pipeline:
Remote URL
│
▼
Provider
│
▼
Materialization
│
▼
Workspace
│
▼
Rendering
Workspace-backed Sources
Remote content is synchronized before rendering.
Source Provider
│
▼
Fetch
│
▼
Workspace
│
▼
Page Rendering
Pages never perform network requests directly.
This enables:
- deterministic builds
- reproducible outputs
- offline builds
- reusable cached content
Conditional HTTP Requests
Whiskey minimizes unnecessary downloads through HTTP cache validation.
Metadata
│
▼
Conditional Request
│
├── 304 Not Modified
│ │
│ ▼
│ Reuse Workspace
│
└── 200 OK
│
▼
Update Workspace
Supported headers:
- ETag
- Last-Modified
HTML Extraction
HTML sources are automatically normalized into Markdown.
HTTP
│
▼
Content-Type
│
├── text/html
│
▼
Defuddle
│
▼
Markdown
│
▼
Workspace
This keeps the rendering pipeline content-format agnostic.
Offline Builds
Synchronize once:
whiskey sync
Then build anywhere.
whiskey build --offline
Remote sources are served entirely from the workspace.
Themes
Whiskey ships with four bundled themes.
- minimal — Clean and minimal
- terminal — Hacker-inspired terminal aesthetic
- paper — Traditional document style
- noir — Dark editorial layout
Themes consist of:
- layouts
- partials
- static assets