Static sites
with a good beat.
bongo turns Markdown, templates, and assets into fast static HTML. Rolldown bundles your scripts. LightningCSS bundles your styles.
---
title: Hello, world
date: 2024-05-01
tags: [js, css]
---
# Hello, world

<bongo:card title="Hello" count=3 featured /> Plain files in. A static site out.
Each folder has one job. bongo reads them in order and writes plain HTML, CSS, and JS to public/.
assets/ scripts, styles, fonts content/ pages: .md, .hbs, .html data/ JSON, YAML, modules → $data layouts/ html.hbs wraps each page partials/ reusable template pieces public/ the build output bongo.config.ts site, helpers, plugins
- 1
Load
bongo loads
bongo.config.tsand every file indata/. - 2
Render
Loaders turn content into HTML. Layouts and partials wrap each page.
- 3
Bundle
Rolldown builds scripts. LightningCSS builds styles.
Bun.Imageresizes images. - 4
Write
Pages go to
public/, with content hashes in every asset URL.
Built for content sites.
Markdown and templates
Write Markdown with @bongo/markdown. Wrap it in tempura layouts and partials.
Scripts and styles
Rolldown bundles scripts. LightningCSS bundles, nests, prefixes, and minifies CSS.
Images, sized for you
Bun.Image resizes images, converts them to WebP, and adds srcset, width, and height.
Data in, JSON out
Files in data/ become $data. Data modules write JSON, such as /search.json.
Feeds and sitemaps
Write sitemap.xml.hbs as an output file. Add RSS or Atom with @bongo/feed.
Smooth navigation
bongo/client adds client-side navigation, view transitions, and prefetch.
One typed config.
Set your site, helpers, and plugins in bongo.config.ts. Templates read them as $site and $utils.
- Loads the same in Bun, Deno, and Node 24+.
- Change it while
bongo devruns, and every page rebuilds. No restart. - A failed build shows an error overlay. The last good build keeps serving.
import { markdown } from '@bongo/markdown';
import { shiki } from '@bongo/markdown/highlight';
import type { Config } from 'bongo';
export default {
$site: {
title: 'My Site',
url: 'https://example.com/',
lang: 'en',
},
plugins: [
markdown({
highlighter: shiki({ theme: 'github-dark' }),
}),
],
} satisfies Config;<!doctype html>
<html lang="{{ $site.lang }}">
<head>
<title>{{ $page.title }} — {{ $site.title }}</title>
<bongo:style src="style.css"></bongo:style>
</head>
<body>
{{{ $page.content }}}
<bongo:client transitions prefetch />
</body>
</html>import type { Build } from 'bongo';
export default ({ $pages }: Build.Data) => $pages
.filter(page => page.section === 'blog')
.map(page => ({ title: page.title, path: page.path }));