fssg is a portable, dependency-free static site generator written entirely
in POSIX shell and AWK. It recursively processes markdown and html
files in src/ and outputs a minified, deployable website in dist/.
-
Pure Shell & POSIX-Compliant No runtime dependencies beyond
sh,awk,sed,find,cp, etc. -
Markdown & HTML Support Built-in Markdown-to-HTML parser with support for headings, paragraphs, blockquotes, lists, tables, links, images, code blocks, and more.
-
Templating Global
src/template.htmlwith{{title}}and{{content}}placeholders, plus{{BASE_URL}}for proper asset paths. -
Includes & Blocks
{{ include:foo.html }}and{{ include-block:foo.html param="value" }}for reusable snippets with optional Markdown processing. -
Conditional Rendering
{{ IF_EXT:md }}...{{ ENDIF_EXT }}or{{ IF_PAGE:about.html }}to show/hide content based on file extension or output path. -
Asset Pipeline Copies
src/static/todist/static/, hoists<style>and<script>blocks to appropriate locations. -
Developer Conveniences Watch mode (
-w), built-in server (-swith multiple server options), auto-open (-o), parallel builds (-jwith default of 100), and auto-reload functionality.
- A POSIX-compliant shell (
sh,bash,dash,zsh, etc.) - Standard POSIX utilities:
awk,sed,find,cp,mkdir,rm,chmod, etc.
wget https://raw.githubusercontent.com/xlc-dev/fssg/main/fssg
chmod +x fssgPlace fssg in your project root.
If you intend to use the built-in server (-s) you may also want the mongoose binaries:
git clone https://github.com/xlc-dev/fssg.git
cp fssg/fssg ./my-site/
cp -r fssg/mongoose ./my-site/mongoose/
chmod +x ./my-site/fssg- Create your project structure (see next section).
- Write content in
src/as.mdor.html. - Run the generator:
./fssg- Browse output in
dist/.
your-project/
├── fssg # shell script
└── src/
├── template.html # global layout ({{title}}, {{content}})
├── index.md # page content (Markdown or HTML)
├── about.html # additional pages
├── includes/ # reusable snippets
│ └── header.html
└── static/ # CSS, images, fonts, etc.
└── img/
└── logo.png
template.html: contains your<head>/<body>skeleton.src/*.md|html: content files—Markdown is auto-converted.src/includes/: files for{{ include:... }}and{{ include-block:... }}.src/static/: copied verbatim todist/static/.
./fssg [options]
-h, --helpShow help and exit-V, --versionPrint the script's version and exit-q, --quietQuiet mode (errors only)-v, --verboseVerbose mode (build details)-n, --nocolorNo color in output-w, --watchWatchsrc/for changes and rebuild-s, --serveStart local server (prefers mongoose, falls back to python)-o, --openAuto-open browser (requires-s)-m, --minifyDisable HTML minification (enabled by default)-j <num>Parallel build jobs (default: 100)
FSSG_BASE_URL: Base URL for the website (default: empty string)FSSG_SERVER_CMD: Override the server command used by-sFSSG_SERVER_PORT: Port used by the dev server (default: 8000)FSSG_AWK: Custom command for the awk executable (default: awk)FSSG_AWK_OPTS: Custom options for the awk executable (default: none)
src/index.md:
{{title: Home}}
# Welcome to My Site
This site is generated by **fssg**.src/template.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>{{title}}</title>
<link rel="stylesheet" href="{{BASE_URL}}/static/style.css" />
</head>
<body>
{{content}}
</body>
</html>./fssg # builds the page to dist/index.htmlsrc/includes/footer.html:
<footer>
<p>© 2025 My Company</p>
</footer>Usage in a page:
{{ include:footer.html }}src/includes/alert.html:
<div class="alert alert-{{type}}">
<h4>{{alert_title}}</h4>
{{content}}
</div>Usage in a page:
{{ include-block:alert.html type="warning" alert_title="Attention"
markdown="true" }} This is **Markdown** content inside the block. {{ endinclude
}}{{ IF_EXT:md }}
<p>This only appears in Markdown-converted pages.</p>
{{ ENDIF_EXT }} {{ IF_PAGE:about.html }}
<p>This only appears in Markdown-converted pages.</p>
{{ ENDIF_PAGE }}# Build with verbose output
./fssg -v
# Build and start server with auto-reload
./fssg -s -w -o
# Build with 200 parallel jobs for large sites
./fssg -j 200-
Style & Script Hoisting: All
<style>tags move to<head>,<script>tags to end of<body>, preserving discovery order. -
Minification: Enabled by default, removes HTML comments, extra whitespace, and CSS/JS comments. Disable with
-mfor debugging. -
Auto-reload: When using
-wor-s, fssg injects a script that polls/.reloadto trigger browser refreshes on changes. -
Server Selection: The
-sflag prefers a local./mongoosebinary, then systemmongoose, then falls back to Python's HTTP server. -
Parallel Processing: Pages are processed in parallel child processes with configurable concurrency (default: 100).
For full details, see the fssg Documentation Website.
This project is licensed under the MIT License. See LICENSE for details.