Zerodown is a lightning-fast, zero-configuration static site generator that transforms your Markdown content into beautiful, fast-loading websites. Perfect for personal blogs, portfolios, and documentation sitesβwithout the headache!
- π Content-focused: Write in Markdown, focus on your content
- π§© Modular architecture: Clean separation of concerns for easy maintenance
- π Smart asset handling: Links and images work correctly in both your editor and the final site
- π¨ Theme support: Easily switch between different CSS themes
- β‘ Fast builds: Efficient processing for quick development cycles
- ποΈ No database required: Everything is stored as files
- π Zero configuration: Works out of the box with sensible defaults
- π₯οΈ Beautiful CLI: Rich, colorful terminal output with progress tracking
- π Interactive Shell: Command-line shell for streamlined workflow
- π Python 3.7 or higher
- π¦ Pip for installing dependencies
You can install Zerodown in two ways:
-
Clone this repository:
git clone https://github.com/yourusername/zerodown.git cd zerodown
-
Install the package:
pip install -e .
If you just want to try Zerodown without installing it:
- Clone the repository as above
- Run the included script:
python zd_cli.py
π‘ Pro tip: Use a virtual environment to keep your dependencies isolated!
-
Initialize a new site with one of the example templates:
# For a blog (creates config.yaml by default) zerodown init my-blog --template blog # For a portfolio zerodown init my-portfolio --template portfolio # For a minimal site zerodown init my-site --template basic # If you prefer Python configuration zerodown init my-site --template basic --config-format py
-
Configure your site: Edit
config.yaml
(orconfig.py
if you chose Python format) in your project directory to set your site title, description, and other settings.
-
Copy an example template:
# For a blog cp -r examples/blog my-blog # For a portfolio cp -r examples/portfolio my-portfolio # For a minimal site cp -r examples/basic my-site
-
Configure your site: Edit
config.yaml
(orconfig.py
) in your project directory to set your site title, description, and other settings. -
Add content:
- π Place Markdown files in the
content/
directory - π Organize content into sections (e.g.,
content/notes/
,content/projects/
) - π§© Add reusable content fragments in
content/_includes/
(e.g.,bio.md
,contact-info.md
) - πΌοΈ Store images and other assets in
content/assets/
- π Create
content/home.md
for your homepage content with shortcodes
- π Place Markdown files in the
-
Customize templates:
- ποΈ Edit HTML templates in the
templates/
directory - π¨ Create or modify CSS themes in the
styles/
directory
- ποΈ Edit HTML templates in the
-
Build your site:
# If you installed the package zerodown build /path/to/your/site # Or using the CLI script python zd_cli.py build /path/to/your/site
-
Preview locally:
# If you installed the package zerodown serve /path/to/your/site # Or using the CLI script python zd_cli.py serve /path/to/your/site
Then visit
http://localhost:8000
in your browser. β¨
your-site/
βββ config.yaml # Site configuration
βββ content/ # All your Markdown content
β βββ home.md # Homepage content with shortcodes
β βββ about.md # Top-level pages
β βββ _includes/ # Reusable content fragments
β β βββ bio.md # Can be included in other pages with {% include "bio.md" %}
β βββ assets/ # Images and other files
β β βββ ...
β βββ posts/ # Content section (defined in config)
β β βββ post1.md # Individual content items
β β βββ post2.md
β βββ projects/ # Another content section (defined in config)
β βββ project1.md # Individual content items
β βββ project2.md
βββ templates/ # HTML templates
β βββ base.html # Base template with common elements
β βββ index.html # Homepage template
β βββ post.html # Template for individual posts
β βββ post_list.html # Template for section index pages
βββ styles/ # CSS styles
β βββ main.css # Main stylesheet
βββ _site/ # Generated output (created by build)
βββ index.html # Generated homepage
βββ about.html # Generated top-level pages
βββ posts/ # Generated section directories
β βββ index.html # Section index page
β βββ post1.html # Generated content pages
β βββ post2.md.html
βββ styles/ # Copied and processed styles
βββ assets/ # Copied assets
π‘ Tip: The structure is flexibleβorganize your content in a way that makes sense for your project!
Each Markdown file can include metadata at the top:
---
title: "My First Post"
date: 2025-03-29
description: "This is my first post"
featured: true # Can be used to mark featured content
image: "hero.jpg" # Featured image for the content
---
# Content starts here
You can use standard Markdown syntax for links and images:
[Link to another page](another-page.md)

Zerodown automatically adjusts paths to work correctly in the final site. No more broken links! π
You can specify image dimensions directly in your Markdown using a special syntax in the alt text:

This will set the width to 300px and height to 200px in the generated HTML. You can specify either width, height, or both. If dimensions aren't specified, images will be responsively sized with sensible defaults:
- Images will be limited to the content width
- Aspect ratio will be maintained
- Images will be centered in the content area
Shortcodes allow you to include dynamic content directly in your Markdown files:
## Latest Posts
[latest_posts count="3" section="posts"]
## Explore Sections
[section_list]
## Featured Content
[featured_items count="2"]
-
[latest_posts]
: Displays the latest posts from a sectioncount
: Number of posts to display (default: 3)section
: Section key to get posts from (default: "posts")
-
[section_list]
: Lists all sections or items in a sectionsection
: Optional section key to list items from
-
[featured_items]
: Displays content items marked as featured in their frontmattercount
: Number of items to display (default: 3)section
: Optional section key to limit featured items to a specific section
Zerodown includes an interactive shell for a more streamlined workflow. This allows you to enter commands directly without having to type the full command each time.
To start the interactive shell, simply run the CLI script without any arguments:
python zd_cli.py
You'll see a welcome message and a prompt where you can enter commands:
Zerodown v0.1.0 Interactive Shell
Welcome to Zerodown v0.1.0 interactive shell!
Type 'help' or '?' to list commands.
zerodown>
The shell supports all the same commands as the regular CLI, plus some additional navigation commands:
-
build
: Build your sitezerodown> build examples/blog zerodown> build --verbose
-
init
: Initialize a new sitezerodown> init my-new-site --template blog
-
serve
: Start a local development serverzerodown> serve --port 8080
-
cd
: Change directoryzerodown> cd examples/blog
-
pwd
: Show current directoryzerodown> pwd
-
ls
: List files in current or specified directoryzerodown> ls content
-
help
: Show help for a commandzerodown> help build
-
exit
orquit
: Exit the shell
All commands support the same verbosity flags as the regular CLI:
-q
: Quiet mode (errors only)-v
: Normal verbosity (detailed information)-vv
: Verbose mode (maximum detail)
π‘ Philosophy: Shortcodes keep all content decisions in Markdown files while templates remain purely structural, maintaining a clean separation of concerns.
Zerodown follows a clean, modular approach to generate static sites from your Markdown content. Here's how it works:
+----------------+ +----------------+ +----------------+
| | | | | |
| Configuration +---->+ Content Files +---->+ Templates |
| (config.yaml) | | (Markdown) | | (HTML/Jinja2) |
| | | | | |
+-------+--------+ +--------+-------+ +-------+--------+
| | |
| | |
v v v
+-------+---------------------------------------------+--------+
| |
| Build Process |
| |
| 1. Load configuration |
| 2. Set up template environment |
| 3. Process includes and assets |
| 4. Process content sections |
| - Parse Markdown files (with shortcodes) |
| - Build individual pages |
| - Build section index pages |
| 5. Build homepage and top-level pages |
| 6. Copy static assets and styles |
| |
+-------------------------------+------------------------------+
|
|
v
+-----------+-----------+
| |
| Generated Site |
| (_site directory) |
| |
+-----------------------+
-
Configuration Loading:
- Load settings from
config.yaml
orconfig.py
- Set up paths, site information, and section definitions
- Load settings from
-
Template Setup:
- Initialize Jinja2 environment with the template directory
- Register custom filters and functions
-
Content Processing:
- Process
_includes
directory for reusable content fragments - For each content section defined in the config:
- Find all Markdown files in the section directory
- Parse frontmatter metadata
- Convert Markdown to HTML
- Process shortcodes (like
[latest_posts]
or[section_list]
) - Apply the appropriate template
- Generate individual pages and section index pages
- Process
-
Asset Handling:
- Copy static assets from
static/
to the output directory - Process and copy CSS from
styles/
to the output directory - Fix relative paths in links and image sources
- Copy static assets from
-
Output Generation:
- Write all processed files to the
_site/
directory - Maintain the directory structure for sections
- Write all processed files to the
Zerodown follows these core principles:
- Content/Code Separation: All content lives in Markdown files, all presentation logic in templates
- No Content Opinions in Templates: Templates should be purely structural with no hardcoded content
- Dynamic Content via Shortcodes: Use shortcodes in Markdown to include dynamic elements
- Simplicity First: Sensible defaults that work out of the box
- Flexibility: Easy to customize for different site types
After building your site, the _site/
directory contains all the files needed for your website. You can deploy these files to any static hosting service:
- π GitHub Pages: Push the
_site/
directory to a GitHub repository - β‘ Netlify: Connect your repository and set the publish directory to
_site/
- πΌ Vercel: Similar to Netlify, with automatic deployments
- βοΈ Amazon S3: Upload the
_site/
directory to an S3 bucket configured for static website hosting
π‘ Pro tip: Set up a GitHub Action to automatically build and deploy your site whenever you push changes!
Zerodown supports two configuration formats:
YAML configuration is simpler and more user-friendly, perfect for non-technical users:
# config.yaml
# Site information
site_name: My Website
site_description: A beautiful static site
base_url: / # Use "/" for local development, or your domain for production
# Directory paths
content_dir: content
template_dir: templates
styles_dir: styles
static_dir: static
output_dir: _site
# Theme settings
theme_css_file: main.css # The CSS file to use from the styles directory
# Content sections
sections:
posts:
title: Blog Posts
template: post.html # Template for individual posts
list_template: post_list.html # Template for the section index page
sort_by: date # Sort items by this metadata field
reverse_sort: true # Sort in reverse order (newest first)
# Navigation items
nav_items:
- title: Home
url: /
- title: Blog
url: /posts/
- title: About
url: /about.html
Python configuration offers more flexibility for advanced users:
# config.py
# Site information
SITE_NAME = "My Website"
SITE_DESCRIPTION = "A beautiful static site"
BASE_URL = "/" # Use "/" for local development, or your domain for production
# Directory paths
CONTENT_DIR = "content"
TEMPLATE_DIR = "templates"
STYLES_DIR = "styles"
STATIC_DIR = "static"
OUTPUT_DIR = "_site"
# Theme settings
THEME_CSS_FILE = "main.css" # The CSS file to use from the styles directory
# Content sections
SECTIONS = {
"posts": {
"title": "Blog Posts",
"template": "post.html",
"list_template": "post_list.html",
"sort_by": "date",
"reverse_sort": True
}
}
# Navigation items
NAV_ITEMS = [
{"title": "Home", "url": "/"},
{"title": "Blog", "url": "/posts/"},
{"title": "About", "url": "/about.html"}
]
π‘ Note: When both
config.yaml
andconfig.py
exist, the YAML configuration takes precedence.
-
Add a new section to your configuration file:
In YAML (config.yaml):
sections: projects: title: Projects template: project.html # Template for individual items list_template: project_list.html # Template for section index sort_by: date reverse_sort: true
Or in Python (config.py):
"projects": { "title": "Projects", "template": "project.html", "list_template": "project_list.html", "sort_by": "date", "reverse_sort": True }
-
Create the corresponding directory in
content/
:mkdir -p content/projects
-
Add Markdown files to the new section. That's it! π
-
Add a new CSS file in the
styles/
directory:cp styles/main.css styles/my-theme.css
-
Edit the CSS file to customize the appearance.
-
Update your configuration to use your new theme:
In YAML (config.yaml):
theme_css_file: my-theme.css
Or in Python (config.py):
THEME_CSS_FILE = "my-theme.css"
π Style tip: Check out CSS frameworks like Water.css or Pico.css for quick, beautiful styling!
Zerodown is organized into modular components:
zerodown/
βββ zerodown/ # Core package (the framework)
β βββ __init__.py # Package initialization
β βββ builder.py # Main build orchestration
β βββ cli.py # Command-line interface
β βββ config.py # Configuration handling
β βββ content.py # Content processing
β βββ markdown.py # Markdown handling with link/asset processing
β βββ templates.py # Template handling
β βββ utils.py # Utility functions
βββ examples/ # Example sites
β βββ basic/ # Minimal example
β βββ blog/ # Blog template
β βββ portfolio/ # Portfolio template
βββ setup.py # Package installation
βββ run_zerodown.py # Script to run without installing
This modular architecture ensures a clean separation between the framework and your content, making it easy to upgrade Zerodown without affecting your site.
utils.py
: Utility functions
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE.md file for details.