Etch is a minimalist, Python-based web framework for content-driven websites. It uses plain Markdown files, zero build steps, and Flask to serve content dynamically — perfect for personal blogs, digital résumés, and project portfolios.
Etch was designed with a bias toward simplicity and transparency. If you're a Python developer who wants to avoid bloated static site generators, Etch might feel like home.
- Markdown-first publishing model with YAML frontmatter
- No build step — content is rendered at request time
- Fully Pythonic and hackable (Flask + Jinja2)
- Easy customization with minimal boilerplate
- Smart caching for fast reads
- AI-assisted architecture (Claude 3.5)
etch/
├── app.py # Main Flask app and routes
├── utils.py # Markdown parsing, helpers, caching
├── config.yml # Site config (paths, author info, etc.)
├── auth.py # Admin login + password hashing
├── templates/ # Jinja2 HTML templates
├── posts/ # Markdown files for blog posts
├── pages/ # Static pages (e.g., About)
├── projects/ # Markdown-based project entries
├── static/ # CSS, JS, images
pip install -i https://test.pypi.org/simple/ etch
Where new-site
is the name of your folder (or .
if you want to create the app in your current directory):
etch new-site
Optionally, add --bare
/-b
if you don't want the demo content!
cd new-site
flask run # or python app.py
Visit http://localhost:5000
git clone https://github.com/rgkimball/etch.git
cd etch
python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
python app.py
Visit http://localhost:5000
Now make an edit, add a page or a post and your content will be live — no need to restart the app!
All content lives in the posts/
, pages/
, and projects/
directories. Each file must:
- Be written in Markdown
- Begin with a YAML frontmatter block like this:
---
title: My First Post
date: 2025-07-01
tags: [ai, flask]
summary: A quick walkthrough of building Etch with Claude 3.5
---
Here's the main content...
Edit config.yml
to change:
- Site title, author, description
- Post pagination
- Content directory paths
- Admin password hash (for future features)
- Templates live in
/templates
and use Jinja2 - CSS and assets go in
/static
- Routes can be edited in
app.py
- Add or remove content types by modifying the
CONTENT_TYPES
registry inutils.py
auth.py
includes login helpers, but admin routes are not enabled by default. Future versions may include editing from the browser.
Because sometimes you don’t need a JS toolchain, Go templates, or a megabyte of YAML. You just want to write, commit, and publish in a familiar language.