Etch
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.
Features
- 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)
Project Structure
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
Quickstart - from PyPI
1. Install the package
pip install etch
2. Create a new project
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!
3. Run the app server
cd new-site
flask run # or python app.py
Visit http://localhost:5000
Quickstart - from source
1. Clone the repo
git clone https://github.com/rgkimball/etch.git
cd etch
2. Create a virtual environment (optional but recommended)
python3 -m venv venv
source venv/bin/activate
3. Install dependencies
pip install -r requirements.txt
4. Run the development server
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!
Writing Content
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...
Configuration
Edit config.yml to change:
- Site title, author, description
- Post pagination
- Content directory paths
- Admin password hash (for future features)
Customizing
- Templates live in
/templatesand use Jinja2 - CSS and assets go in
/static - Routes can be edited in
app.py - Add or remove content types by modifying the
CONTENT_TYPESregistry inutils.py
Admin
auth.py includes login helpers, but admin routes are not enabled by default. Future versions may include editing from the browser.
Why Etch?
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.
Metadata
Release files for etch 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| etch-0.1.0.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| etch-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 36.9 kB
Release files / etch-0.1.0.tar.gz
| Download URL | etch-0.1.0.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5fa98a29f74987939900f04e74341da748057935e8ed0e0e2b642b96aaee7fa4
|
|
BLAKE2b-256 checksum How to use checksums |
6d208503bf896d2910935972b42e0da6893eb20dc7d46952f815d7545394bf78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.3
|
Release files / etch-0.1.0-py3-none-any.whl
| Download URL | etch-0.1.0-py3-none-any.whl |
|---|---|
| Size | 18.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e837bd51853d77a819dc4c660ac4a4ce3aa9862899336aac63bd865b26f549f2
|
|
BLAKE2b-256 checksum How to use checksums |
b86b3032192713384332d63b047ed44ea83e2b5f7b551b7ae4e1825729139ef9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.11.3
|