Skip to main content

scaffld

English · Español: README.es.md

Python License: MIT

Scaffold a new, fully-wired Python project in seconds — with a friendly terminal UI.

scaffld generates a clean project skeleton (src layout, tests, typed code, CI, pre-commit, license, and an optional virtualenv) from extensible templates. No cookiecutter YAML to memorize, no {% raw %} gymnastics to keep GitHub Actions files intact — just answer a few prompts and start writing code.

pip install scaffld
scaffld new

Features

  • Interactive TUI built with Rich — pick a template from a table, confirm a summary, watch the file tree appear.
  • Batteries included — every project ships with pyproject.toml, a src/ layout, pytest tests that pass out of the box, a GitHub Actions matrix CI, a .pre-commit-config.yaml, a real LICENSE, and a sensible .gitignore.
  • Three built-in templates — python-lib, python-cli, and python-api (FastAPI).
  • GitHub-Actions-safe templating — a tiny custom engine leaves ${{ ... }} expressions untouched, so your workflow files render correctly with zero escaping.
  • Extensible — drop your own template folder in ~/.scaffld/templates and it shows up instantly. Templates are just a template.toml plus a files/ tree.
  • Scriptable — --no-input makes scaffld behave in CI and Makefiles.
  • Zero-config virtualenv — optionally creates .venv for the new project.

Install

pip install scaffld
# or, from a clone:
pip install -e ".[dev]"

scaffld is on PyPI, so pip install scaffld works. Installing from a clone instead needs git on your machine.

Requires Python 3.9+. Runtime dependencies: typer and rich (plus tomli on 3.9/3.10).

Usage

List the available templates:

$ scaffld list
                              Available templates
┏━━━┳━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ # ┃ Template   ┃ Kind    ┃ Description                                       ┃
┡━━━╇━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ 1 │ python-api │ api     │ FastAPI service with a health route, typed        │
│   │            │         │ handlers, and CI.                                 │
│ 2 │ python-cli │ cli     │ Zero-dependency argparse CLI with a               │
│   │            │         │ console-script entry point.                       │
│ 3 │ python-lib │ library │ Importable Python library: src/ layout, typed     │
│   │            │         │ API, tests, and CI.                               │
└───┴────────────┴─────────┴───────────────────────────────────────────────────┘

Create a project. Run scaffld new with no arguments for the full interactive flow, or pass flags to skip the prompts:

$ scaffld new "Weather Bot" -t python-cli -a "Ada Lovelace" -d "A tiny weather CLI." --no-input --no-venv
weather-bot/
├── .github/
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── README.md
├── pyproject.toml
├── src/
│   └── weather_bot/
│       ├── __init__.py
│       └── cli.py
└── tests/
    └── test_cli.py
╭──────────────────────────────────── Done ────────────────────────────────────╮
│ Created 9 files in /tmp/weather-bot                                          │
╰──────────────────────────────────────────────────────────────────────────────╯

Next steps:
  cd weather-bot
  pip install -e ".[dev]"
  pytest

scaffld show python-lib prints the file tree a template would generate, without writing anything to disk.

The generated project is real and works immediately:

$ cd weather-bot && pip install -e ".[dev]" && pytest -q
...                                                                        [100%]
3 passed in 0.01s

$ weather-bot Fernando
Hello, Fernando!

Useful flags

Flag Meaning
-t, --type Template to use (scaffld list).
-a, --author Author name (defaults to SCAFFLD_AUTHOR, then git config user.name, then $USER).
--email Author email (defaults to SCAFFLD_EMAIL, then git config user.email).
-d, --description One-line project description.
-l, --license MIT, BSD-3-Clause, ISC, or none.
-o, --output Directory to create the project in (defaults to the current directory).
--python Minimum Python version for the generated project (3.N or 3.N.P).
--venv / --no-venv Create a .venv in the new project. On by default.
--no-input Never prompt — fail if a required value is missing (great for CI).
--force Write into a non-empty directory.

scaffld -V (or --version) prints the version and exits.

How it works

A template is just a directory:

my-template/
├── template.toml        # name, kind, description
└── files/               # the tree that gets rendered
    ├── pyproject.toml
    ├── src/{{ package_name }}/__init__.py
    └── ...

Both file contents and path segments are rendered, so a directory literally named {{ package_name }} becomes weather_bot/ on disk.

The rendering engine is deliberately small and has one property that matters for real projects: unknown {{ ... }} expressions are left untouched. That means a GitHub Actions file can contain ${{ matrix.python-version }} right next to a scaffld variable like {{ project_name }}, and only the latter is substituted — no escaping required. It also supports filters ({{ project_name | snake }}) and nestable conditionals ({% if has_license %}...{% endif %}).

Derived variables are computed once and kept consistent: give it "Weather Bot" and you get package_name = weather_bot, project_slug = weather-bot, a filled-in license, the year, and more. Names are transliterated to ASCII first, so "Café Búho" yields cafe_buho rather than a shredded caf_b_ho, and a name that collides with a Python keyword gets a trailing underscore (class → class_) so the package stays importable.

Custom templates

Point scaffld at your own templates by dropping them in ~/.scaffld/templates/ (or any directory listed in the SCAFFLD_TEMPLATES environment variable). A user template that shares a name with a built-in one shadows it, so you can override the defaults. Available variables include project_name, package_name, project_slug, author, author_email, description, license, python_version, and year.

Development

python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest

Part of the ferinazumaDEV ecosystem

scaffld is one of a family of small, focused open-source tools I build and maintain. If it saved you some project-setup time, a few of the sibling projects tackle neighbouring problems in the same practical, batteries-included spirit.

  • The GEO Handbook — the open reference on getting content cited by AI answer engines (ChatGPT, Perplexity, Google AI Overviews, Gemini, Copilot).
  • politeclient — a careful, well-behaved HTTP client for Python: retries with backoff, per-host rate-limiting, caching, and pagination.
  • typedout — reliable structured output from OpenAI and Anthropic, with a provider interface for others: schema-validated JSON with tolerant repair and retries.
  • webhook-replay — capture a webhook once, then replay it at your local app as many times as you need.
  • Hub & writing: zentimes.es.

By ferinazumaDEV.

License

MIT — see LICENSE.


Built by Fernando (@ferinazumaDEV).

Metadata

Release files for scaffld 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for scaffld 0.1.2
File Size Uploaded
scaffld-0.1.2.tar.gz 34.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for scaffld 0.1.2
File Interpreter ABI Platform
scaffld-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 67.3 kB

Release files / scaffld-0.1.2.tar.gz

Download URL scaffld-0.1.2.tar.gz
Size 34.1 kB
Tags Source
SHA-256 checksum
How to use checksums
ed04f9cc51f5670ca1ed2965985c79f80a78851f00bca9a754a9a4c678b072fa
BLAKE2b-256 checksum
How to use checksums
04cc786b12e15e68ee1b2ffcdfb30be89af4d667535cd1a1e5c248f0cf8681ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release files / scaffld-0.1.2-py3-none-any.whl

Download URL scaffld-0.1.2-py3-none-any.whl
Size 33.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8ec55c1f043ffd6dfaf7223010bc28982ba8e8c56c94b2e26171db432fbbab2a
BLAKE2b-256 checksum
How to use checksums
dbf9428e6bbb191c317877d691180692108b0596db555a78a01a5cccbaeba4d2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 13, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page