Python static site generator built on free-threading — every layer pure Python, scales with your cores, zero npm
Project description
ᓚᘏᗢ Bengal
The documentation generator built on Python's free-threading future
Every layer — markdown parsing, syntax highlighting, templates, dev server — is pure Python, scales with your cores, and ships zero npm dependencies.
pip install bengal
bengal new site --name mysite && cd mysite && bengal serve
Why Bengal?
Bengal is a static site generator where the entire stack is Python you can read, debug, and extend. No JavaScript toolchains. No compiled C extensions in the critical path. Every library in the pipeline — Patitas (markdown), Rosettes (syntax highlighting), Kida (templates), Pounce (dev server) — is purpose-built for Python 3.14+ free-threading.
What this gets you:
- Scales with cores — Parallel builds with true thread parallelism on Python 3.14t. No GIL contention.
- AI-native output — Generates llms.txt, agent manifests, per-page JSON, and Content Signals so AI agents can discover, navigate, and respect your content policies.
- Sub-second rebuilds — Provenance-based incremental builds with content-addressed hashing. Only changed pages rebuild.
- Python-native workflows — Jupyter
.ipynbrendering, autodoc for Python/CLI/OpenAPI,pip installand go. - Batteries included — Sitemap, RSS, social cards, search indexes, broken link detection, content validation.
- Extensible — Pluggable engines for templates, Markdown, and syntax highlighting. 9 plugin extension points.
Use Bengal For
- Documentation sites — Versioned docs, API reference, search, and internal linking
- Blogs and journals — Tags, categories, feeds, related content, and social sharing
- Knowledge bases — Markdown-first publishing with validation and JSON search indexes
- Product and marketing sites — Landing pages, content collections, and social cards
Quick Commands
| Command | Description |
|---|---|
bengal build |
Production build |
bengal serve |
Dev server with live reload |
bengal preview |
Build, then serve completed output locally |
bengal check |
Health checks and validation |
bengal fix |
Auto-fix common issues |
bengal inspect graph |
Site structure analysis |
Aliases: b (build), s (serve), v (check)
Site Scaffolding
Interactive Wizard — Guided setup with presets
Run without arguments for a guided experience:
bengal new site
The wizard prompts for site name, base URL, and presents preset options:
🎯 What kind of site are you building?
📝 Blog - Personal or professional blog
📚 Documentation - Technical docs or guides
💼 Portfolio - Showcase your work
🛒 Product - Product site with listings and features
📄 Resume - Professional resume/CV site
📦 Blank - Empty site, no initial structure
⚙️ Custom - Define your own structure
Each preset creates a complete site with appropriate sections, sample content, and configuration.
Direct Template Selection — Skip prompts with explicit options
Create sites non-interactively with --template:
bengal new site --name my-docs --template docs
bengal new site --name my-blog --template blog
bengal new site --name portfolio --template portfolio
Available templates:
| Template | Description | Sections Created |
|---|---|---|
default |
Basic site structure | Home page only |
blog |
Personal/professional blog | blog, about |
docs |
Technical documentation | getting-started, guides, reference |
portfolio |
Showcase work | about, projects, blog, contact |
product |
Product site with listings | products, features, pricing, contact |
resume |
Professional CV | Single resume page |
landing |
Single-page landing | Home, privacy, terms |
changelog |
Release notes timeline | Changelog with versions |
Add Pages and Templates — Expand without recreating
Add content and template files to an existing Bengal site:
# Add a page under a section
bengal new page --name getting-started --section docs
# Add template files
bengal new layout --name docs-page
bengal new partial --name docs-sidebar
# Add a content type strategy scaffold
bengal new content-type --name tutorial
Use frontmatter, content type strategies, and section index pages to shape how new content is grouped and rendered.
Content Type Scaffolds — Python-defined content behavior
Generate a starter ContentTypeStrategy when a section needs custom matching,
template selection, summaries, or pagination behavior:
bengal new content-type --name changelog
The generated file contains TODO markers for matching, template selection, excerpt generation, and pagination so custom content behavior stays in Python.
Features
| Feature | Description | Docs |
|---|---|---|
| SEO & Discovery | Sitemap, RSS, canonical URLs, Open Graph, social cards, search, JSON/LLM output, llms.txt, Content Signals | SEO & Discovery → |
| Directives | Tabs, admonitions, cards, dropdowns, code blocks | Content → |
| Notebooks | Native Jupyter .ipynb rendering, Binder/Colab links |
Notebooks → |
| Autodoc | API docs from Python, CLI, OpenAPI with symbol cross-linking, @overload grouping, and inherited-member badges |
Autodoc → |
| Remote Sources | Pull content from GitHub, Notion, REST APIs | Sources → |
| Image Processing | Resize, crop, format conversion (WebP/AVIF), srcset generation | Images → |
| Content Collections | Type-safe frontmatter with dataclass/Pydantic schemas | Collections → |
| Theming | Dark mode, responsive, syntax highlighting, search | Theming → |
| Validation | Health checks, broken link detection, auto-fix | Building → |
| Performance | Parallel builds, incremental rebuilds, streaming | Large Sites → |
| Zero-Config Deploy | Auto-detects GitHub Pages, Netlify, Vercel | Deployment → |
📚 Full documentation: lbliii.github.io/bengal
Configuration
Single-file — Simple projects
# bengal.toml
[site]
title = "My Site"
baseurl = "https://example.com"
Directory-based — Multi-environment projects
config/
├── _default/ # Base configuration
│ ├── site.yaml
│ └── build.yaml
├── environments/ # Environment overrides
│ └── production.yaml
└── profiles/ # Build profiles
└── dev.yaml
bengal build --environment production # Production environment
bengal build --profile dev # Development profile
📖 Configuration guide: Configuration →
Project Structure
mysite/
├── content/ # Markdown pages
├── templates/ # Custom templates (optional)
├── assets/ # Static files (CSS, JS, images)
├── data/ # YAML/JSON data files
├── config/ # Configuration directory
└── public/ # Build output
Theming
Bengal ships with a modern, accessible default theme:
- Dark mode with system preference detection
- Responsive design with mobile navigation
- Syntax highlighting with copy buttons
- Table of contents with scroll spy
- Full-text search (Lunr.js)
Customize templates:
{# templates/page.html #}
{% extends "base.html" %}
{% block content %}
<article class="prose">
<h1>{{ page.title }}</h1>
{{ content | safe }}
</article>
{% endblock %}
Pluggable Engines
Bengal follows a "bring your own" pattern — swap engines without changing your content.
Template Engine
| Engine | Description | Install |
|---|---|---|
| Kida | Bengal's native engine. AST-native, free-threading safe, Jinja2-compatible syntax | Built-in |
Kida is the built-in template engine. It uses Jinja2-compatible syntax, so existing Jinja2 templates generally work without changes. See the Kida migration guide if migrating from Jinja2.
Markdown Parsers
| Parser | Description | Install |
|---|---|---|
| Patitas (default) | Bengal's native parser. Typed AST, O(n) parsing, thread-safe | Built-in |
| Python-Markdown | Full-featured, extensive extensions | pip install markdown |
| Mistune | Removed — selecting it emits a DeprecationWarning and falls back to Patitas |
Deprecated alias |
# config/_default/content.yaml
markdown:
parser: patitas # default, or python-markdown (requires: pip install markdown)
Syntax Highlighters
| Backend | Description | Install |
|---|---|---|
| Rosettes (default) | Lock-free, 55+ languages, O(n) guaranteed | pip install rosettes |
# config/_default/theme.yaml
highlighting:
backend: rosettes
Custom backends can be registered via register_backend().
Requirements
- Python 3.14+ (uses free-threading and PEP 784 compression)
- Linux, macOS, Windows
Philosophy
Bengal prioritizes correctness and clarity over backwards compatibility.
Each release represents the best solution we know how to deliver. When existing behavior no longer reflects the best design, it changes. Upgrades may require reading release notes and making adjustments.
- Fail loudly — Breaking changes produce clear errors
- User control — You choose when to upgrade; we choose what changes
- Minimal compatibility layers — Where a shim, config-key migration, or command alias exists, it emits a clear
DeprecationWarningwith a documented removal horizon — never silent behavior
If you need multi-year stability, pin your version.
Documentation
Development
git clone https://github.com/lbliii/bengal.git
cd bengal
uv sync --group dev
pytest
Bengal is a standalone uv project. Run uv sync and uv run ... from this checkout; sibling repositories are not required for normal development.
The Bengal Ecosystem
A structured reactive stack — every layer written in pure Python for 3.14t free-threading.
| ᓚᘏᗢ | Bengal | Static site generator ← You are here | Docs |
| ∿∿ | Purr | Content runtime | — |
| ⌁⌁ | Chirp | Web framework | Docs |
| =^..^= | Pounce | ASGI server | Docs |
| )彡 | Kida | Template engine | Docs |
| ฅᨐฅ | Patitas | Markdown parser | Docs |
| ⌾⌾⌾ | Rosettes | Syntax highlighter | Docs |
Python-native. Free-threading ready. No npm required.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file bengal-0.4.2.tar.gz.
File metadata
- Download URL: bengal-0.4.2.tar.gz
- Upload date:
- Size: 3.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
335c2084034616da9b355a8c20b0803ead06813318e2dbbf124f25f9d98c9ad1
|
|
| MD5 |
9fdaf874c09ae81381de47d32da8e1d1
|
|
| BLAKE2b-256 |
d5921ea4b6667ea23590801e98be5f67291e3a6b10c200fbac6b4618d0369ff4
|
Provenance
The following attestation bundles were made for bengal-0.4.2.tar.gz:
Publisher:
python-publish.yml on lbliii/bengal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bengal-0.4.2.tar.gz -
Subject digest:
335c2084034616da9b355a8c20b0803ead06813318e2dbbf124f25f9d98c9ad1 - Sigstore transparency entry: 1826330093
- Sigstore integration time:
-
Permalink:
lbliii/bengal@eeccdbc009fab3709cee4d63b9f489056359461a -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/lbliii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@eeccdbc009fab3709cee4d63b9f489056359461a -
Trigger Event:
release
-
Statement type:
File details
Details for the file bengal-0.4.2-py3-none-any.whl.
File metadata
- Download URL: bengal-0.4.2-py3-none-any.whl
- Upload date:
- Size: 4.1 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a2b724c7717da4168acd0c58f8addddbf5d1a23d1ea7e42325eb7154405632cc
|
|
| MD5 |
9a17c390aea6954c3b55c25e451fc407
|
|
| BLAKE2b-256 |
c86392700e23435fa1667db155a2fd7a51af634a04c3f43f7867a4c3b0cc6f85
|
Provenance
The following attestation bundles were made for bengal-0.4.2-py3-none-any.whl:
Publisher:
python-publish.yml on lbliii/bengal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
bengal-0.4.2-py3-none-any.whl -
Subject digest:
a2b724c7717da4168acd0c58f8addddbf5d1a23d1ea7e42325eb7154405632cc - Sigstore transparency entry: 1826330137
- Sigstore integration time:
-
Permalink:
lbliii/bengal@eeccdbc009fab3709cee4d63b9f489056359461a -
Branch / Tag:
refs/tags/v0.4.2 - Owner: https://github.com/lbliii
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@eeccdbc009fab3709cee4d63b9f489056359461a -
Trigger Event:
release
-
Statement type: