README.md

# tilstream

A small static site generator for Today-I-Learned notes. Feed it a folder of
short markdown files and it spits out HTML, an RSS feed, and a JSON search
index.

I wrote this because I kept writing 200-word TILs and wanted somewhere cheap
and boring to put them. Hugo felt like overkill for a directory of one-page
notes; tilstream is ~900 lines of Go and does only what I need.

## Install

    go install mercemay.top/src/tilstream@latest

Or clone and build:

    git clone https://mercemay.top/src/tilstream.git
    cd tilstream
    go build -o tilstream .

## Layout

Point tilstream at a directory that looks like this:

    notes/
      2025-01-18-ripgrep-iglob.md
      2025-01-12-sqlite-wal-checkpoint.md
      2024-12-30-xargs-n1-buffering.md

Each file has YAML front-matter:

    ---
    title: "ripgrep --iglob for case-insensitive globs"
    date: 2025-01-18
    tags: [cli, ripgrep]
    ---

    Body in regular CommonMark markdown. Code fences are fine, footnotes work.

## Build

    tilstream build --src notes --out public

`public/` now holds `index.html`, one HTML file per note, `feed.xml`, and
`search.json`. Drop the folder behind any static host.

## Develop

    tilstream serve --src notes --port 8080

Starts an HTTP server and re-renders on file changes. Uses fsnotify with a
150ms debounce so saving a file in Neovim doesn't trigger three rebuilds.

## Flags

    build     render to disk
      --src           source directory (default: .)
      --out           output directory (default: public)
      --drafts        include posts with draft: true
      --template      override templates/post.tmpl
      --base-url      used in RSS and OG tags

    serve     dev server with live reload
      --src, --out as above
      --port          HTTP port (default: 8080)

## Search

`search.json` is a flat array of `{title, url, tags, body}` pairs. The
template embeds a ~40-line vanilla JS snippet that does a substring match
on title+tags+body. Good enough for 200 TILs; replace with Pagefind if you
outgrow it.

## Why not Hugo/Zola/Eleventy?

I wanted the source to fit in my head. Every subsystem lives in one file in
`internal/`. No themes, no shortcodes, no content types. If you want any of
those things, use Hugo.

## License

MIT. See `LICENSE`.