Registry / devops / copier

copier

JSON →
library9.17.2pypypi✓ verified 24d ago

Copier is a versatile Python library and CLI tool designed for rendering project templates. It supports both local paths and Git URLs as template sources, allowing for dynamic replacement of values in various text files using Jinja2 templating. It handles project generation and updates, ensuring existing files are not overwritten unless explicitly instructed. The library is actively maintained with frequent updates, providing a robust solution for scaffolding and managing project lifecycles.

pip install copier
INSTALL
IMPORT
SIG · COPIER
C
copier
devopspythonv9.17.2
Install
5.5s avg
Import
1470ms
Disk
52MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v9.17.2 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.95 runs
installs and imports cleanly · install 0.0s · import 1.516s · 54.8MB
glibc
py 3.103.95 runs
installs and imports cleanly · install 5.5s · import 1.424s · 55MB
52MB installed
● package 52MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

run_copy
from copier import run_copy
from copier import copy
The `copy` function was used in older versions of Copier. As of recent major versions (e.g., Copier 9.x), `run_copy` is the canonical and preferred function for programmatically copying templates, offering explicit parameters instead of `**kwargs`.

This quickstart demonstrates how to programmatically use `copier.run_copy` to generate a new project from a local template. It first creates a minimal template directory with a `copier.yml` and a Jinja2-templated file, then copies it to a destination, providing answers as a dictionary. The generated project's README content is then printed.

import os import shutil from pathlib import Path from copier import run_copy # Define paths for demonstration template_path = Path('./my_template') dest_path = Path('./my_new_project') # Clean up previous runs for idempotent quickstart if dest_path.exists(): shutil.rmtree(dest_path) if template_path.exists(): shutil.rmtree(template_path) # 1. Create a dummy template structure template_path.mkdir(exist_ok=True) (template_path / 'copier.yml').write_text( """ # questions project_name: type: str help: What is your project name? author_name: type: str default: 'John Doe' """ ) (template_path / '{{ project_name }}').mkdir() (template_path / '{{ project_name }}' / 'README.md.jinja').write_text( """ # {{ project_name }} This project was generated by {{ author_name }}. """ ) print(f"Template created at: {template_path.resolve()}") # 2. Programmatically copy the template # In a real scenario, these answers might be interactively prompted or passed via CLI answers = { 'project_name': 'MyAwesomeProject', 'author_name': 'AI Assistant' } run_copy( str(template_path), str(dest_path), data=answers, overwrite=True # Use with caution in real projects ) print(f"Project generated at: {dest_path.resolve()}") print("Generated README.md content:") print((dest_path / 'MyAwesomeProject' / 'README.md').read_text()) # Clean up after quickstart shutil.rmtree(template_path) shutil.rmtree(dest_path)
copier --version
Debug
Known issues
breakingCopier 9.x and newer requires Python 3.10 or higher. Older versions supported Python 3.6+.
fix
Ensure your environment uses Python 3.10 or a more recent version. Upgrade your Python interpreter if necessary.
affects: 9.x.x and newer
breakingThe `_copier_conf.json()` method for accessing configuration data within templates has been removed.
fix
Replace all instances of `_copier_conf.json()` in your templates with `_copier_conf|to_json` to correctly render JSON representations of the configuration.
affects: 9.14.0 and newer
gotchaWhen updating a project, Copier handles merge conflicts by default using 'inline' markers, similar to Git merge conflicts. This can leave `<<<<<<<`, `=======`, `>>>>>>>` markers in your files.
fix
To generate separate `.rej` files for conflicts instead of inline markers, use the `--conflict rej` option when running `copier update` or `copier recopy`.
affects: All versions
gotchaIf your Copier template uses custom Jinja extensions or other Python packages for tasks, these dependencies must be installed in the same Python environment where Copier itself is installed. Copier does not automatically manage template-specific Python dependencies.
fix
Manually install any additional Python packages required by your template's custom logic into the environment where Copier is running (e.g., `pip install copier my-template-extension`). Consider using `pipx` for isolated Copier installations and then injecting template-specific dependencies into that `pipx` environment.
affects: All versions
gotchaWhen writing custom Python code for Copier templates (e.g., post-copy tasks, custom Jinja extensions), be mindful of mutable default arguments in function definitions. Changes to these mutable defaults (e.g., lists, dictionaries) will persist across multiple calls, leading to unexpected behavior.
fix
Initialize mutable default arguments to `None` and assign the mutable object inside the function if `None` is passed. Example: `def func(arg=None): arg = arg if arg is not None else []`.
affects: All versions (general Python footgun)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'copier'
The 'copier' library is not installed in the Python environment being used, or the Python interpreter cannot find it in its `sys.path`.
fix
Install the library using pip: `pip install copier` or, if using Poetry, `poetry add copier`.
jinja2.exceptions.UndefinedError: 'variable' is undefined
A variable referenced within a Jinja2 template (e.g., in a `copier.yml` question's `default` or directly in a template file) was not provided by the user, a default value, or the template context.
fix
Ensure all variables used in templates are defined either through `copier.yml` questions, a `default` filter (`{{ my_variable | default('some_value') }}`), or are correctly passed into the template context.
copier: error: unrecognized arguments
This often occurs after upgrading to `copier` version 8.0.0 or later, where subcommand usage became mandatory. Commands like `copier ./template ./destination` were changed to require a subcommand, e.g., `copier copy ./template ./destination`.
fix
Prepend the appropriate subcommand (`copy`, `update`, `recopy`) to your `copier` command. For example, change `copier SRC DST` to `copier copy SRC DST`.
Error: There are conflicts in the generated files. Please review them.
During a `copier update` operation, changes in the original template conflict with modifications made directly in the generated project. Copier cannot automatically merge these changes.
fix
Manually resolve the conflicts. Copier often leaves `.rej` files or `<<<<<<<` markers in affected files. After resolving, `git add` the files and commit. You can also specify conflict handling with `--conflict rej` or `--conflict inline`.
Upgrade
Version history
9.17.2latest on PyPI · released Aug 19, 2026
Audit
Dependencies
GitrequiredRequired for using Git repository templates and version control functionality during updates.
Jinja2requiredUsed as the templating engine for rendering dynamic content in templates. It is an indirect dependency of `copier`.
Agent activity
13 hits · last 30 days
node
12
Resources
copier — pip install copier · libregistry