Skip to content
Back to skills

421 Copier 380036ff

ASecurity

**What problem does it solve?** Copier solves the problem of project scaffolding AND ongoing template synchronization. Unlike most templating tools that are one-way generators, Copier enables **code lifecycle management** - you can update existing projects when the template evolves, not just generate new projects.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 11, 2026
developmentjavascriptpythonrustgojavabashsqlreactnodefastapi

Works with

  • cli
  • api

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro shows the line behind each finding and how to fix it

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 421-copier_380036ff --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 421 Copier 380036ff?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 421 Copier 380036ff
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-421-copier-380036ff/badge)](https://www.skillsdirectory.com/skills/tools-only-421-copier-380036ff)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
---
title: 'Copier: Project Template Renderer with Update Capabilities'
library_name: copier
pypi_package: copier
category: project_templating
python_compatibility: 3.9+
last_updated: '2025-11-02'
official_docs: https://copier.readthedocs.io
official_repository: https://github.com/copier-org/copier
maintenance_status: active
---

# Copier: Project Template Renderer with Update Capabilities

## Executive Summary

**What problem does it solve?** Copier solves the problem of project scaffolding AND ongoing template synchronization. Unlike most templating tools that are one-way generators, Copier enables **code lifecycle management** - you can update existing projects when the template evolves, not just generate new projects.

**Core value proposition:**

- Generate projects from templates (scaffolding)
- **Update projects when templates change** (unique feature)
- Version-aware migrations during updates
- Works with local paths and Git URLs
- Preserves customizations during updates

**When you'd be "reinventing the wheel" without it:**

- Maintaining multiple similar projects that need to stay in sync with best practices
- Rolling out security updates or dependency changes across many projects
- Applying organizational standards to existing codebases
- Managing project boilerplate that evolves over time

## Official Information

- **Repository**: @<https://github.com/copier-org/copier>
- **PyPI Package**: `copier` (current: v9.10.3)
- **Documentation**: @<https://copier.readthedocs.io/>
- **License**: MIT
- **Maintenance**: Active development, 2,880+ stars
- **Original Author**: jpsca (Juan-Pablo Scaletti)
- **Current Maintainers**: yajo, pawamoy, sisp, and community

## Installation

```bash
# As CLI tool (recommended)
pipx install copier
# or with uv
uv tool install copier

# As library
pip install copier

# With conda
conda install -c conda-forge copier

# Nix (100% reproducible)
nix profile install 'https://flakehub.com/f/copier-org/copier/*.tar.gz'

# Homebrew (macOS/Linux)
brew install copier
```

**Requirements:**

- Python 3.9 or newer
- Git 2.27 or newer (for template versioning and updates)

## Python Version Compatibility

| Python Version | Support Status       | Notes                                          |
| -------------- | -------------------- | ---------------------------------------------- |
| 3.9 - 3.12     | ✅ Full support      | Production ready                               |
| 3.13           | ✅ Supported         | v9.10.2+ built with Python 3.13.7              |
| 3.14           | ⚠️ Likely compatible | Not explicitly tested, but backward-compatible |
| < 3.9          | ❌ Not supported     | Use older Copier versions                      |

_Source: @<https://github.com/copier-org/copier/blob/master/pyproject.toml> (classifiers section)_

## Core Purpose: When to Use Copier

### Primary Use Cases

1. **Project Scaffolding with Future Updates**

   - Generate new projects from templates
   - Apply template updates to existing projects
   - Track which template version each project uses

2. **Multi-Project Standardization**

   - Maintain consistency across microservices
   - Roll out organization-wide best practices
   - Synchronize CI/CD configurations

3. **Living Templates**

   - Templates that evolve with ecosystem changes
   - Security patches propagated to all projects
   - Dependency updates across project families

4. **Template Versioning**
   - Use Git tags to version templates
   - Selective updates to specific versions
   - Smart diff between template versions

### Copier vs Cookiecutter vs Yeoman

**Use Copier when:**

- ✅ You need to update projects after generation
- ✅ You manage multiple similar projects
- ✅ Your template evolves frequently
- ✅ You want migration scripts during updates
- ✅ You prefer YAML over JSON configuration

**Use Cookiecutter when:**

- ✅ You only need one-time generation
- ✅ You want the largest template ecosystem
- ✅ You need maximum stability (mature project)
- ✅ Template updates aren't important

**Use Yeoman when:**

- ✅ You're in the Node.js ecosystem
- ✅ You want NPM package distribution
- ✅ You need JavaScript-based logic

| Feature                  | Copier                  | Cookiecutter           | Yeoman      |
| ------------------------ | ----------------------- | ---------------------- | ----------- |
| **Template Updates**     | ✅ Yes                  | ❌ No (requires Cruft) | ❌ No       |
| **Migrations**           | ✅ Yes                  | ❌ No                  | ❌ No       |
| **Config Format**        | YAML                    | JSON                   | JavaScript  |
| **Templating**           | Jinja2                  | Jinja2                 | EJS         |
| **Programming Required** | ❌ No                   | ❌ No                  | ✅ Yes (JS) |
| **Template Suffix**      | `.jinja` (configurable) | None                   | You choose  |
| **File Name Templating** | ✅ Yes                  | ✅ Yes                 | ✅ Yes      |
| **Ecosystem Size**       | Medium                  | Large                  | Large       |
| **Maturity**             | Active                  | Mature                 | Mature      |

_Source: @<https://github.com/copier-org/copier/blob/master/docs/comparisons.md>_

## Real-World Examples

### 1. FastAPI Full-Stack Template

**Repository**: @<https://github.com/fastapi/full-stack-fastapi-template> (38,000+ stars)

```bash
# Generate a new FastAPI project
pipx run copier copy https://github.com/fastapi/full-stack-fastapi-template my-project --trust
```

**Features demonstrated:**

- Multi-service Docker setup
- PostgreSQL integration
- React frontend scaffolding
- Environment variable templating
- Post-generation tasks

**Template snippet** (@<https://github.com/fastapi/full-stack-fastapi-template/blob/main/copier.yml>):

```yaml
project_name:
  type: str
  help: The name of the project
  default: FastAPI Project

secret_key:
  type: str
  help: |
    The secret key for the project, generate with:
    python -c "import secrets; print(secrets.token_urlsafe(32))"
  default: changethis

_tasks:
  - ["{{ _copier_python }}", .copier/update_dotenv.py]
```

### 2. Modern Python Package Template (copier-uv)

**Repository**: @<https://github.com/pawamoy/copier-uv> (108 stars)

```bash
# Create a uv-managed Python package
copier copy gh:pawamoy/copier-uv /path/to/project
```

**Features demonstrated:**

- uv package manager integration
- Jinja extensions (custom filters)
- Git integration (auto-detect author)
- License selection (20+ options)
- Multi-file configuration includes

**Advanced configuration** (@<https://github.com/pawamoy/copier-uv/blob/main/copier.yml>):

```yaml
_min_copier_version: "9"
_jinja_extensions:
  - copier_template_extensions.TemplateExtensionLoader
  - extensions.py:CurrentYearExtension
  - extensions.py:GitExtension
  - extensions.py:SlugifyExtension

author_fullname:
  type: str
  help: Your full name
  default: "{{ 'Default Name' | git_user_name }}"

repository_name:
  type: str
  default: "{{ project_name | slugify }}"
```

### 3. NLeSC Scientific Python Template

**Repository**: @<https://github.com/NLeSC/python-template> (223 stars)

**Features demonstrated:**

- Modular configuration (YAML includes)
- Profile-based generation
- Research software best practices
- Citation files (CITATION.cff)

**Modular structure** (@<https://github.com/NLeSC/python-template/blob/main/copier.yml>):

```yaml
# Include pattern for maintainability
!include copier/settings.yml !include copier/profiles.yml !include copier/questions/essential.yml !include copier/questions/features_code_quality.yml !include copier/questions/features_documentation.yml
```

### 4. JupyterLab Extension Template

**Repository**: @<https://github.com/jupyterlab/extension-template> (77 stars)

```bash
pip install "copier~=9.2" jinja2-time
copier copy --trust https://github.com/jupyterlab/extension-template .
```

### 5. Odoo/Doodba Template

**Repository**: @<https://github.com/Tecnativa/doodba-copier-template> (104 stars)

- Complex multi-container applications
- Multiple answer files for different template layers

## Integration Patterns

### Git Integration

**Template versioning with Git tags:**

```bash
# Copy specific version
copier copy --vcs-ref=v1.2.0 gh:org/template /path/to/project

# Copy latest release (default)
copier copy gh:org/template /path/to/project

# Copy from HEAD (including uncommitted changes)
copier copy --vcs-ref=HEAD ./template /path/to/project
```

**Update to latest template version:**

```bash
cd /path/to/project
copier update  # Reads .copier-answers.yml automatically
```

**Update to specific version:**

```bash
copier update --vcs-ref=v2.0.0
```

### Template Updates Workflow

The **killer feature** that distinguishes Copier:

```mermaid
graph TD
    A[Template v1.0] --> B[Generate Project]
    B --> C[.copier-answers.yml]
    A --> D[Template v2.0]
    D --> E[copier update]
    C --> E
    E --> F[Smart 3-way Merge]
    F --> G[Updated Project]
    F --> H[Migration Scripts]
    H --> G
```

**The update process:**

1. Copier clones template at old version (from `.copier-answers.yml`)
2. Regenerates project with old template
3. Compares to current project (detects your changes)
4. Clones template at new version
5. Generates with new template
6. Creates 3-way merge between: old template → your project ← new template
7. Runs migration tasks for version transitions

**Example migration** (from Copier docs):

```yaml
# copier.yml
_migrations:
  - version: v2.0.0
    command: rm ./old-folder
    when: "{{ _stage == 'before' }}"
  - invoke migrate $VERSION_FROM $VERSION_TO
```

### CI/CD Integration

**GitHub Actions example:**

```yaml
name: Update from template
on:
  schedule:
    - cron: "0 0 * * 0" # Weekly
  workflow_dispatch:

jobs:
  update:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v5
      - run: uv tool install copier
      - run: copier update --defaults --vcs-ref=HEAD
      - run: |
          git config user.name "Bot"
          git config user.email "bot@example.com"
          git checkout -b update-template
          git add -A
          git commit -m "Update from template"
          git push origin update-template
      - uses: peter-evans/create-pull-request@v5
```

### Multiple Templates per Project

Apply different templates to different aspects:

```bash
# Base framework
copier copy -a .copier-answers.main.yml \
  gh:example/framework-template .

# Pre-commit config
copier copy -a .copier-answers.pre-commit.yml \
  gh:my-org/pre-commit-template .

# Internal CI
copier copy -a .copier-answers.ci.yml \
  git@gitlab.internal.com:templates/ci .
```

Each gets its own answers file, enabling independent updates:

```bash
copier update -a .copier-answers.main.yml
copier update -a .copier-answers.pre-commit.yml
copier update -a .copier-answers.ci.yml
```

## Usage Examples

### Basic Template Creation

**Minimal template structure:**

```text
my_template/
├── copier.yml              # Template configuration
├── .git/                   # Git repo (for versioning)
├── {{project_name}}/       # Templated folder name
│   └── {{module_name}}.py.jinja  # Templated file
└── {{_copier_conf.answers_file}}.jinja  # Answers file
```

**copier.yml** (question definitions):

```yaml
project_name:
  type: str
  help: What is your project name?

module_name:
  type: str
  help: What is your Python module name?
  default: "{{ project_name | lower | replace('-', '_') }}"

python_version:
  type: str
  help: Minimum Python version
  default: "3.9"
  choices:
    - "3.9"
    - "3.10"
    - "3.11"
    - "3.12"
    - "3.13"
```

**Templated Python file** (`{{project_name}}/{{module_name}}.py.jinja`):

```python
"""{{ project_name }} - A Python package."""

__version__ = "0.1.0"

def hello() -> str:
    """Return a greeting."""
    return "Hello from {{ module_name }}!"
```

**Answers file template** (`{{_copier_conf.answers_file}}.jinja`):

```yaml
# Changes here will be overwritten by Copier
{ { _copier_answers | to_nice_yaml - } }
```

### Generating a Project

**From local template:**

```bash
copier copy /path/to/template /path/to/destination
```

**From Git URL:**

```bash
copier copy https://github.com/org/template /path/to/destination
# or shorthand
copier copy gh:org/template /path/to/destination
copier copy gl:org/template /path/to/destination  # GitLab
```

**With pre-answered questions:**

```bash
copier copy \
  --data project_name="My Project" \
  --data module_name="my_project" \
  gh:org/template /path/to/destination
```

**From data file:**

```bash
# answers.yml
project_name: My Project
module_name: my_project
python_version: "3.11"

# Use it
copier copy --data-file answers.yml gh:org/template /path/to/destination
```

### Programmatic Usage

```python
from copier import run_copy, run_update

# Generate new project
run_copy(
    "https://github.com/org/template.git",
    "/path/to/destination",
    data={"project_name": "My Project"},
    vcs_ref="v1.0.0",  # Specific version
)

# Update existing project
run_update(
    "/path/to/destination",
    vcs_ref="v2.0.0",  # Update to v2.0.0
    skip_answered=True,  # Don't re-ask answered questions
)
```

### Advanced Template Features

**Conditional file generation:**

```yaml
# copier.yml
use_docker:
  type: bool
  help: Include Docker support?
  default: true
```

**File/folder structure:**

```text
template/
  {% if use_docker %}Dockerfile{% endif %}.jinja
  {% if use_docker %}docker-compose.yml{% endif %}.jinja
```

**Dynamic choices:**

```yaml
language:
  type: str
  choices:
    - python
    - javascript

package_manager:
  type: str
  help: Which package manager?
  choices: |
    {%- if language == "python" %}
    - pip
    - uv
    - poetry
    {%- else %}
    - npm
    - yarn
    - pnpm
    {%- endif %}
```

**File exclusion:**

```yaml
_exclude:
  - "*.pyc"
  - __pycache__
  - .git
  - .venv
  - "{% if not use_docker %}docker-*{% endif %}"
```

**Post-generation tasks:**

```yaml
_tasks:
  - git init
  - git add -A
  - git commit -m "Initial commit from template"
  - ["{{ _copier_python }}", -m pip install -e .]
```

**Jinja2 extensions:**

```yaml
_jinja_extensions:
  - copier_templates_extensions.TemplateExtensionLoader
  - jinja2_time.TimeExtension
# Install with:
# pipx inject copier copier-templates-extensions jinja2-time
```

### Updating Projects

**Update to latest version:**

```bash
cd /path/to/project
copier update
```

**Update with conflict resolution:**

```bash
# Inline conflicts (default)
copier update --conflict=inline

# .rej files (like patch)
copier update --conflict=rej
```

**Re-answer questions:**

```bash
# Re-answer all questions
copier update --vcs-ref=:current:

# Skip previously answered
copier update --skip-answered
```

**Update without interactive prompts:**

```bash
# Use defaults/existing answers
copier update --defaults

# Override specific values
copier update --data python_version="3.12"
```

## When NOT to Use Copier

### Simple File Copying

❌ **Don't use Copier for:**

```bash
# Just copy static files
cp -r template_dir new_project
```

✅ **Use basic tools instead:**

- `cp` for simple directory copying
- `rsync` for file synchronization
- Git clone for exact repository copies

### One-Time Generation Without Updates

If you never plan to update from the template:

- Cookiecutter has larger ecosystem
- Yeoman for Node.js projects
- Manual copying might suffice

### Complex Conditional Logic

❌ **Not ideal for:**

- Heavy business logic in templates
- Complex data transformations
- Runtime configuration (use proper config libraries)

✅ **Use instead:**

- Python scripts for complex logic
- Dedicated config management (Dynaconf, python-decouple)
- Application frameworks (Django, FastAPI built-in scaffolding)

### Single Project Maintenance

If you only maintain one project:

- Template overhead isn't justified
- Direct edits are simpler
- No synchronization benefits

### Non-Text Files

Copier focuses on text file templating:

- Binary files copied as-is
- No image/binary manipulation
- No archive extraction

### Version Control Conflicts

⚠️ **Be cautious when:**

- Project has diverged significantly from template
- Many conflicting changes expected
- Team unfamiliar with 3-way merge resolution

**Mitigation:**

- Test updates in separate branch
- Use `--conflict=rej` for manual review
- Document update procedures

## Decision Matrix

### Use Copier When

| Scenario                           | Why Copier?                                                  |
| ---------------------------------- | ------------------------------------------------------------ |
| Managing 5+ similar microservices  | Templates sync security patches across all services          |
| Organizational standards evolving  | Roll out changes without manual edits to each project        |
| Onboarding new projects frequently | Consistent structure + ability to improve template over time |
| Template still experimental        | Iterate template, update existing projects with improvements |
| CI/CD pipeline standardization     | Update all projects when pipeline requirements change        |
| Multi-repo architecture            | Maintain consistency without monorepo complexity             |

### Don't Use Copier When

| Scenario                                    | Why Not?                     | Alternative                           |
| ------------------------------------------- | ---------------------------- | ------------------------------------- |
| Single project, no similar projects planned | Overhead > benefit           | Direct editing                        |
| Template is 100% stable forever             | Update feature unused        | Cookiecutter (larger ecosystem)       |
| Heavy runtime configuration needed          | Wrong tool for job           | Dynaconf, Pydantic Settings           |
| Binary file manipulation required           | Not designed for this        | Pillow, custom scripts                |
| Project has deviated >50% from template     | Merge conflicts overwhelming | Manual migration                      |
| No Git repository for template              | Can't track versions         | Use Git or accept one-shot generation |

### Copier vs Cookiecutter Decision Tree

```text
Do you need to update projects after generation?
├─ YES → Use Copier
│   └─ Need version-aware migrations?
│       ├─ YES → Definitely Copier
│       └─ NO → Still Copier (future-proofing)
│
└─ NO → Consider factors:
    ├─ Prefer YAML config? → Copier
    ├─ Want larger template ecosystem? → Cookiecutter
    ├─ Need maximum stability? → Cookiecutter
    └─ Might need updates later? → Copier (easier to start with)
```

## Best Practices

### Template Design

1. **Version your templates** - Use Git tags (v1.0.0, v2.0.0)
2. **Keep templates focused** - One concern per template
3. **Provide good defaults** - Minimize required answers
4. **Document migrations** - Explain breaking changes
5. **Test template updates** - Generate project, modify, update

### Project Maintenance

1. **Commit `.copier-answers.yml`** - Essential for updates
2. **Don't edit generated markers** - Copier overwrites them
3. **Test updates in branches** - Merge after verification
4. **Run migrations carefully** - Review before executing
5. **Document deviations** - Note why you diverge from template

### Organization Adoption

1. **Start with one template** - Prove value before expanding
2. **Automate update checks** - CI job for template freshness
3. **Train on merge conflicts** - 3-way merges need understanding
4. **Maintain template changelog** - Help consumers understand changes
5. **Version template conservatively** - Breaking changes = major version

## Common Gotchas

1. **Answers file location matters** - Must be committed and at project root
2. **Template suffix required by default** - Files need `.jinja` unless configured otherwise
3. **Git required for updates** - Template must be Git repository with tags
4. **Jinja syntax in YAML** - Must quote templated values properly
5. **Task execution order** - Tasks run sequentially, not in parallel
6. **Conflict resolution** - Learn 3-way merge basics before first update

## Performance Considerations

- **Generation speed**: Fast for typical projects (<1s for small templates)
- **Update speed**: Depends on project size and Git history
- **Memory usage**: Minimal, dominated by Git operations
- **Caching**: Template cloning cached by Git

## Related Tools

- **cruft** - Adds update capability to Cookiecutter templates
- **cookiecutter** - Popular Python templating (one-way generation)
- **yeoman** - Node.js ecosystem scaffolding
- **copier-templates-extensions** - Additional Jinja filters for Copier
- **jinja2-time** - Time-based Jinja filters

## Learning Resources

- Official docs: @<https://copier.readthedocs.io/>
- Template browser: @<https://github.com/topics/copier-template>
- Comparisons: @<https://github.com/copier-org/copier/blob/master/docs/comparisons.md>
- Example templates: See "Real-World Examples" section above

## Summary

**Copier is the best choice when:**

- You maintain multiple related projects
- Your templates evolve over time
- You need to propagate changes to existing projects
- You want version-aware template management
- You prefer declarative YAML configuration

**Copier's unique selling point:** The ability to update existing projects when templates change, with intelligent 3-way merging and version-aware migrations.

**Quick start for evaluation:**

```bash
# Install
pipx install copier

# Try popular template
copier copy gh:pawamoy/copier-uv test-project

# Make changes to project, then simulate update
cd test-project
# Edit some files...
copier update --defaults --vcs-ref=HEAD
```

---

**Research completed**: 2025-10-21 **Sources verified**: Official repository, PyPI, documentation, real-world templates **Template examples analyzed**: 5 major templates (FastAPI, copier-uv, NLeSC, JupyterLab, Doodba)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.