Ever find yourself copying an old project, deleting half the files, doing a find-and-replace for the service name, and praying you didn't miss a reference?
I've been there too many times. Cookiecutter is great, but it's another tool to install. curl | bash scripts work until they don't. And templating tools like degit give you files but no variables.
Blueprint already lets you define your dev environment in a .bp file and apply it across machines. Now it also scaffolds entire projects — with interactive prompts, shared template libraries, and zero extra setup.
The Old Way: blueprint render
Blueprint has had render for a while. Point it at a template directory, pass --var KEY=VALUE for every variable, and it generates files:
blueprint render setup.bp \
--template @github:org/templates@main:python-service \
--output ./my-new-api \
--var APP_NAME=my-new-api \
--var PORT=8000
This works great for updating existing projects — CI pipelines, re-rendering after a version bump, etc. But for scaffolding a new project? You have to remember every variable, type out the JSON, check the docs. It's not interactive.
The New Way: blueprint template
The new template command flips the interaction model:
blueprint template @github:org/templates@main:python-service \
--output ./my-new-api
That's it. Blueprint:
-
Resolves the template — local dir,
@github:shorthand, or git URL -
Scans every
.tmplfile for{{ var "NAME" }},{{ toValue "NAME" }}, and{{ default "NAME" "fallback" }} -
Loads defaults from the template's
setup.bpif present - Prompts you for each variable — yellow for required, blue for optional with defaults
-
Renders the full directory tree into
--output, stripping.tmplextensions
The session looks like this:
─── Template Variables ───
APP_NAME (required): my-new-api
PORT (default: 8000): 9000 ← Enter accepts the default
Shared Template Libraries
The real power is sharing templates across your team or org. Create a repository with this structure:
python-service/
setup.bp # var PORT 8000 / var APP_NAME
Dockerfile.tmpl # FROM python:3.12\nEXPOSE {{ var "PORT" }}
entrypoint.sh.tmpl # exec {{ var "APP_NAME" }}
config/
settings.py.tmpl # PORT = {{ default "PORT" "8000" }}
Anyone on your team can scaffold a new service in one command:
blueprint template @github:myorg/templates@main:python-service \
--output ./billing-service
No setup.bp required on their side. No documentation to read. No "what variables do I need to pass?" The template tells them.
CI/CD workflows, too
Blueprint's own drift-check workflow template is scaffolded with:
blueprint template @github:elpic/templates@main:actions/github/drift-check \
--output ./.github \
--var CHECKS='[{"file":"setup.bp","template":"@github:elpic/templates@main:actions/github/integration/go","against":".github/workflows"}]'
Here CHECKS is a JSON array — a perfect case for --var, which skips the prompt for that variable.
Creating Your Own Template
A blueprint template is just a directory with .tmpl files and an optional setup.bp. Three template functions drive the variables:
| Template syntax | Prompt behavior |
|---|---|
{{ var "NAME" }} |
Required — no default shown |
{{ toValue "NAME" }} |
Required — no default shown |
{{ default "NAME" "val" }} |
Optional — shows "val" as default |
Here's a minimal Dockerfile.tmpl:
FROM python:3.12-slim
WORKDIR /app
COPY . .
EXPOSE {{ default "PORT" "8000" }}
CMD ["{{ var "APP_NAME" }}"]
And its companion setup.bp:
var PORT 8000
var APP_NAME
Users running blueprint template against this directory get:
PORT (default: 8000): ← Enter for 8000
APP_NAME (required): ← must provide
Variable Precedence
| Priority | Source |
|---|---|
| 1 (highest) | Value typed at the prompt |
| 2 |
--var KEY=VALUE flag |
| 3 |
var KEY value in template's setup.bp
|
| 4 (fallback) |
{{ default "KEY" "val" }} in template |
Why not just use Cookiecutter?
Cookiecutter is excellent, but:
- It's another install — Python, pipx, or brew. Blueprint is already in your toolchain if you use it for dev environment setup.
-
Template variables require a separate
cookiecutter.json— Blueprint discovers them from the template files themselves. -
Same remote template infra — Blueprint uses the same
@github:shorthand and git caching as its other commands. No new mental model.
What's next
Blueprint's template command is in the latest release. The rendering infrastructure is shared with blueprint render, so remote templates are cached, local overrides work, and drift detection is on the roadmap.
If you maintain internal templates at your company — service scaffolds, CI workflows, config generators — give blueprint template a try. One command, no docs to write, no variables to remember.



Top comments (0)