Thank you for your interest in contributing. This guide covers the development setup and workflow for working on the template itself, not on projects generated from it.
| Tool | Purpose |
|---|---|
| uv | Python package manager |
| Copier | Template engine (uvx copier) |
| pre-commit | Git hook framework (uvx pre-commit) |
| Git | Version control |
# 1. Fork and clone the repository
git clone https://github.com/<your-fork>/copier-fullstack-template.git
cd copier-fullstack-template
# 2. Install pre-commit hooks (including commit-msg for conventional commits)
uvx pre-commit install
uvx pre-commit install --hook-type commit-msg
# 3. Test a local render
uvx copier copy --trust . /tmp/test-projectcopier.yml # Copier engine configuration (questions, defaults, hooks)
template/ # Everything inside here gets rendered by Copier
backend/ # Python backend (FastAPI, Clean Architecture)
frontend/ # React + TypeScript frontend
.github/ # GitHub Actions, Copilot customizations
...
Key rule: only edit files inside template/. Root-level files (copier.yml,
README.md, etc.) are for the template repository itself.
-
Create a feature branch:
git checkout -b feat/your-feature-name
-
Edit template files inside
template/. -
Run pre-commit checks to ensure nothing is broken:
uvx pre-commit run --all-files
-
Test a local render to verify the generated output:
uvx copier copy --trust . /tmp/test-render -
Commit using Conventional Commits:
git commit -m "feat(backend): add Redis cache adapter"
feat/— new features or template capabilitiesfix/— bug fixes in generated outputdocs/— documentation changeschore/— maintenance (CI, dependencies, tooling)
type(scope): description
Types: feat, fix, docs, style, refactor, test,
chore, perf, ci, build, revert
Scopes: backend, frontend, infra, ci, copier, docs
uvx pre-commit run --all-files # Run all pre-commit hooks
uvx copier copy --trust . /tmp/test-render # Render template and verify output- Use
.jinjasuffix for files that need Copier rendering - Use conditional folder names for optional features:
{% if use_ai %}ai{% endif %} - Prefer
{{ project_slug }}over hardcoded package names
- Line length: 88 characters (Ruff/Black standard)
- Type hints on all public functions and methods
- Google-style docstrings on public interfaces
- Clean Architecture: core layer has zero framework imports
- Strict mode enabled
- No
any— useunknownor proper generics - Biome for formatting and linting
- Push your branch and open a PR against
main. - Ensure CI passes (pre-commit hooks + render smoke test).
- Describe what the change does and why.
- Link related issues if applicable.
- Use GitHub Issues
- Include steps to reproduce and expected vs. actual behavior
- For security vulnerabilities, see SECURITY.md
By contributing, you agree that your contributions will be licensed under the MIT License.