bic is an opinionated and minimal static site generator—with a focus on blogs. View the demo or the source.

It uses Pandoc to convert plain Markdown files into HTML. They get templated {{Mustache}}-style with Mo. Hashids is used to generate IDs.


You get the (opinionated) basics of a static site/blog (read: opinionated):

For reproducible builds, I would recommend using bic with Docker:

Essentially, mount your source directory to /src

docker run --rm -v "$PWD":/src

to spit out a build directory with your generated site.

Alternatively, bic is available as a nix flake.

Follow the setting up flakes guide to enable it, then run

nix run github:Pinjasaur/bic --command bic .

to run bic in the current directory and spit out a build directory with your generated site.


bic is strict where necessary to keep it opinionated with a lean scope.


For a fully-featured example, view the demo source code:

$ tree -F --dirsfirst
├── drafts/
│   └──
├── pages/
│   └──
├── posts/
│   ├──
│   └──
├── static/
│   ├── css/
│   │   └── style.css
│   ├── img/
│   │   └── photo.jpg
│   └── js/
│       └── script.js
├── __feed.rss
├── __index.html
├── _footer.html
├── _head.html
├── _header.html
├── entry.html
├── feed.rss
├── index.html
├── page.html
├── robots.txt
└── sitemap.xml


bic uses an .env pattern. This lets you configure required variables and add any extras that can be used within your templates. Talk about batteries included.

A .env file simply contains lines of KEY=value pairs. If you, for whatever reason, want to supply an environment variable at runtime and have it override your .env then use syntax such like:

ENV_VAR="${ENV_VAR:-default value}"

Not-100%-required but highly-recommended config:

Optional, change if needed:


Anything listed above or added additionally to a .env will be available globally within templates.

Some specific keys used within entries (posts or drafts) and pages:

Drafts will have a draft key set. Likewise, posts will have a post key set.

Each entry in posts/*.md or drafts/*.md is rendered against an entry.html.

Each page in pages/*.md is rendered against a page.html.

index.html and feed.rss both use a double-underscore-prefixed template partial of the same name e.g., {{__index}} from __index.html.

sitemap.xml has access to an array of slugs with the slugs key.


There is an order-of-operations for how files are built, as follows:

If you’re not careful, it’s possible you could overwrite an existing file e.g. pages/ and posts/ both map to /test.html. bic uses the Bash builtin noclobber e.g. set -o noclobber to help prevent these situations. This can be disabled by setting BIC_OVERWRITE.


bic in the wild:


bic is built & maintained by Paul.

Buy Me a Coffee at