Set up client projects with CI, containers, hooks, and releases in one command.
scaffold is a bash toolbox for engineers who start client projects often. One command generates a monorepo that is ready for its first pull request, and every project it makes is built, checked and released the same way.
scaffold is pre-1.0, and its versions are git tags.
| What you're doing | Command | Key principle |
|---|---|---|
| Start a project | scaffold new <name> |
One command, one commit |
| Add an app to it | scaffold add <dir> --adapter <adapter> |
Staged, never committed for you |
| Bring in toolbox changes | scaffold update [dir] |
Applied as a patch you review |
| Put it on GitHub | scaffold publish [dir] |
Private by default, main protected |
| See what's available | scaffold list |
The wizard reads the same list |
| Check adapters and services | scaffold lint |
Every one meets the contract |
Run scaffold with no arguments for a wizard that builds the command for you. Flags and
defaults are in Commands.
You need git and mise. mise install
supplies the rest.
git clone https://github.com/ttncode/scaffold.git
cd scaffold
mise install
export PATH="$PWD:$PATH"Then generate a project somewhere outside the toolbox:
cd ~/playground
scaffold new demo-app --web nextjs --api nestjs --db postgresThe framework generators take a few minutes. You get a directory with one commit,
feat: scaffold project. The full run, from generation to a running release, is in
Walk through a first project.
Other requirements
| Needed for | Requirement |
|---|---|
laravel-api, laravel-inertia |
PHP 8.3 or later on the host (ADR-0016) |
scaffold new |
A GitHub owner: SCAFFOLD_GITHUB_OWNER, the signed-in gh user, or git config github.user |
scaffold publish |
gh, signed in |
| CI in a generated project | A .github repository under that owner, holding the reusable workflows (ADR-0005) |
| Running a release | Docker |
| Piece | What It Does |
|---|---|
| Apps | One directory per adapter you pick, each with its own mise.toml |
| Task contract | Every app answers the same nine mise tasks, so CI runs one command per app |
| CI | Five thin workflows that call shared reusable workflows at @v1 |
| Guardrails | lefthook runs prettier, gitleaks and commitlint; Renovate opens dependency bumps |
| Releases | Release Please, container images, and an install.sh that runs the stack with Docker Compose |
| Docs site | VitePress, checked in CI like any app |
.scaffold.toml |
Records the toolbox commit that generated it, for scaffold update |
| Adapter | Flag | Tier |
|---|---|---|
nextjs |
--web |
A |
nestjs |
--api |
A |
laravel-api |
--api |
A |
flask |
--api |
A |
laravel-inertia |
--app |
B |
Tier A runs on every pull request and stays green through every dependency bump. Tier B is verified weekly and whenever its adapter changes (ADR-0012).
| Flag | Services | Default |
|---|---|---|
--db |
mysql, postgres, mongodb, none |
mysql with --api or --app, otherwise none |
--cache |
redis, none |
none |
- Overlay, not presets. Each adapter runs the framework's own generator, then lays scaffold's files on top (ADR-0003).
- Only what you picked. A project gets
common/and the adapters you chose, nothing else (ADR-0004). - No build orchestrator.
misetasks are the only task runner (ADR-0001, ADR-0002). - The released stack must run. A release has to start and serve, not just build (ADR-0021).
| Path | Purpose |
|---|---|
scaffold |
The entry point, one function per command |
lib/ |
The libraries it sources |
adapters/ |
One directory per framework |
services/ |
One directory per database or cache |
common/ |
Copied into every new project |
tests/ |
bats suites and fixtures |
docs/ |
Tour, decisions, runbooks and diagrams |
Client projects start the same way every time, and each hand-made setup drifts a little from
the last. scaffold turns the setup into one command and keeps it consistent: every app speaks
the same task contract, every project shares the same CI, and scaffold update carries later
fixes into projects that already exist.
- Start here: repository map, commands and a reading path
- Tour: how the pieces fit, in nine pages
- Decisions: why they fit that way
- Runbooks: what to do when something specific happens
- Provenance: what is copied from immich
Setup, test lanes, and how to add an adapter or a service are in CONTRIBUTING.md. Report vulnerabilities privately as described in SECURITY.md.
| Name | GitHub | Role | |
|---|---|---|---|
![]() |
Truong Trung Nghia | @ttncode | Creator |
MIT, see LICENSE. A generated project gets no license file, because its terms belong to the engagement it was generated for.

