A static site generator for hackers.
Fast static pages · a proper blog · your developer story — with first-class support
for the agents that help you build it.
cherrybomb.dev · Guides · Design · ADRs · Changelog
CherryBomb is a modern take on Octopress: your site is a repo,
publishing is a task, everything is hackable — without the part where upgrading the
framework ruins your week. The engine is Elixir, the CLI is cherry, and the output
is plain HTML you can host anywhere.
Install
One line, no toolchain:
curl -fsSL https://cherrybomb.dev/install.sh | sh # macOS / Linux
irm https://cherrybomb.dev/install.ps1 | iex # Windows
Upgrading is cherry upgrade — checksum-verified against the release, rustup-style.
Use from Elixir
Cherry is an ordinary hex package; the binary is just a convenience wrapper around it.
Scaffolding: cherry_new
cherry_new is the project generator — a tiny
separate package whose only job is to give you mix cherry.new mysite before you
have Cherry itself, the same pattern Phoenix uses with phx_new. Install it once as
a mix archive and the task is available globally, outside any project:
mix archive.install hex cherry_new
mix cherry.new mysite
The scaffold is a complete site: content directories, a cherry.exs config, a first
post, a GitHub Pages deploy workflow, an AGENTS.md describing the publish loop, and
a mix.exs that depends on the cherry release matching the installer — from there
the site's own {:cherry, "~> 0.1.0-rc.3"} dependency pulls the real framework:
def deps do
[
{:cherry, "~> 0.1.0-rc.3"}
]
end
The tasks
Every cherry <verb> is also mix cherry.<verb>, flag for flag, and every one of
them takes --json for a structured envelope:
| task | what it does |
|---|---|
mix cherry.build | build the site → _site/, plain files, deploy anywhere |
mix cherry.serve | live-reloading dev server, drafts included |
mix cherry.check [--strict] | build in memory, return structured diagnostics — the verifier |
mix cherry.gen.post "Title" | scaffold a dated draft post with valid frontmatter |
mix cherry.publish PATH | flip the draft flag, re-date, move the file |
mix cherry.schema COLLECTION | print a collection's frontmatter schema — never guess |
mix cherry.gen.action | generate the GitHub Pages deploy workflow |
mix cherry.gen.project / gen.talk | portfolio scaffolds (positions, talks) |
mix cherry.gen.theme NAME [--from THEME] | scaffold a site-local theme from an official one |
mix cherry.theme.list / theme.which | inspect available themes and the active one |
mix cherry.theme.eject TEMPLATE | take ownership of one template, with provenance |
mix cherry.theme.diff [--apply] | three-way drift status for every ejected overlay |
mix cherry.upgrade --check | report newer releases (the self-swap itself is binary-only; under mix, upgrade with mix deps.update cherry) |
mix cherry.version | print the version |
As a library
Cherry.build/1 and Cherry.check/1 return structs (Cherry.Build,
Cherry.Check.Diagnostic), so custom tooling composes without shelling out — see
the API docs.
Quickstart
cd mysite
cherry gen.post "Hello, world"
cherry serve # live-reloading dev server
cherry build # → _site/, plain files, deploy anywhere
cherry gen.action # GitHub Pages workflow, done
What you get
Fast static pages. Prerendered HTML, zero JavaScript by default. Enhancements (theme toggle, search) are tiny islands that fail soft.
A blog that behaves. Markdown + YAML frontmatter, validated against a schema at build time — errors name the file and the field. Tags, drafts, future posts, Atom + JSON feeds, sitemap, canonical URLs, OpenGraph and JSON-LD, all default-on.
A developer story, not a résumé. The portfolio is data: positions, projects, talks, open source — rendered as a timeline, cross-linked with your blog through one shared tag taxonomy. The "Elixir" page shows your jobs, projects, and every post you've written about it.
…and a CV when you need one. The same data also renders at /cv/ as a web page
that reads like a CV — link employers to it instead of attaching a file. Every skill
claim links to its evidence in your story, it prints pixel-perfect, exports as
JSON Resume at /cv.json, and has an unlisted mode for quiet job hunts.
Themes you can actually swap. Themes implement a versioned contract (templates + design tokens), so switching is one config line. Customization is a ladder — config → tokens → CSS → eject a template — and ejects record provenance, so theme upgrades three-way-merge instead of silently stranding your copies.
Light and dark, properly. Token-driven, honors system preference, manual toggle wins, no flash of the wrong theme — and code blocks follow along at zero JS cost.
Agents are users too. Every command takes --json and returns structured
results. cherry check verifies links, SEO, and schemas with machine-readable
diagnostics. cherry schema posts --json tells an agent exactly what valid
frontmatter is before it writes. New sites ship an AGENTS.md. Published sites
emit llms.txt and a markdown mirror of every page — readable without scraping.
Host anywhere._site/ is plain files. GitHub Pages is first-class (generated
Actions workflow, correct base-path handling for project pages, CNAME, .nojekyll)
— Netlify, Cloudflare, S3, or rsync work just as well.
Hack it
A Cherry site is a thin Elixir project depending on the cherry package — so a
"plugin" is just a module in your repo hooking a pipeline stage, and a framework
upgrade is a version bump. Binary-mode sites (no mix.exs) extend via extensions/*.exs
scripts and can graduate to a full mix project by adding one file.
Builds are deterministic by contract: same input, byte-identical output.
Status
v0.1.0-rc.3 is out: five release binaries with provenance attestation, the full
authoring loop, the verifier, both themes, the portfolio/CV views, self-upgrade, and
the agent skill. cherrybomb.dev is Cherry's own dogfood,
built from example/ on
every push. Cherry is built in the open, README-first:
DESIGN.md is the
constitution and docs/adr/
records the decisions. Next stop: stable 0.1.0.
License
Dual-licensed under MIT or Apache 2.0 — your choice. Contributions are accepted under the same dual license.
The CherryBomb brand assets (logo, mascot, wordmark, and their derivatives such as the favicon and og-card) are not covered by either license — they may not be reused as your own branding. See assets/LICENSE.