# Copier: a template renderer that keeps its answers inside your project

> Copier renders project templates from a YAML questionnaire and records the answers in a file inside the generated project, which is what lets it update that project later. Its dependency manifest is unusually lopsided, with nothing pinned for users and everything pinned for developers, and its badge markup has no alt text in two of three formats.

**copier-org/copier** — Library and command-line utility for rendering projects templates.

- Repository: https://github.com/copier-org/copier
- Website: https://copier.readthedocs.io/en/stable/
- Stars: 3,612 · Forks: 274
- Language: Python
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/copier-org-copier

## Git is a hard requirement and the version comes from the repository

The installation list has four items and the second one is Git, at a stated minimum version of 2.27. For a tool whose output is text files, that is a real dependency rather than a convenience, and the manifest explains where it comes from. The package declares its version as dynamic, and one of its runtime dependencies is a library whose entire job is to derive a version number from a repository's tags and history. So the installed tool asks git what version it is, which is why the install instructions insist on a recent enough git. It also means the version string is only meaningful if the install came from a clone rather than from a wheel built without repository metadata, and it is the reason the project can publish patch releases without a version constant anywhere in the source. Everything else in the install list is two package managers and a Homebrew formula.

## The answers are written into your project and overwritten on update

The template layout on the page is five lines and the last one is the mechanism. There is a directory named with a configuration key that expands to the answers file, and the file that lives there is a template whose whole body is a comment saying changes will be overwritten, followed by the answers rendered as YAML:

```yaml+jinja title="{{_copier_conf.answers_file}}.jinja"
# Changes here will be overwritten by Copier
{{ _copier_answers|to_nice_yaml -}}
```

So the generated project ships a record of what was answered, written by the tool, and the tool overwrites it on every update. That file is how the tool knows what you were asked last time, which is what lets it re-ask only the questions whose defaults actually changed. It also means your repository contains a generated answers file that is not yours to edit, which is worth knowing before someone tidies it away. The template directory and the templated filenames are rendered through Jinja, and the layout shows both a directory name and a file name being substituted. The filter used to write the answers is an extra Jinja filter, which is why the manifest carries a filter pack for the engine on top of the engine itself.

## Updating a project is opt-in; scaffolding is not

The concepts section splits into three words: templates, which lay out how to generate the subproject, questionnaires, which are configured in the template and whose answers generate projects, and projects, which is where your real program lives and is usually generated or updated from a template. Then there is a section of goals, and it makes a distinction that is easy to miss. Code scaffolding is a goal every template satisfies, and the page says so without qualification. Code lifecycle management, meaning letting consumers update their projects when the template evolves, is the other goal, and it carries the parenthetical that not all templates allow updating. That single clause decides the tool's value for you. If your template only scaffolds, Copier is a better cookiecutter. If it opts in, you get the harder thing: a generated project that can be revised in place when the template changes underneath it.

## Every development dependency is pinned and no runtime dependency is

The manifest's two dependency sections are opposites. The runtime list gives every package a lower bound and, apart from one conditional typing helper on older interpreters, no upper bound. The development group gives every package an exact pin, and it is not a partial discipline: the test runner, the type checker, the linter, the formatter, the pre-commit framework, the task runner, the spell checker and a dozen smaller tools are all pinned to a specific version. Three of them are pinned to dated builds of type stub packages, which means the stubs are refreshed on the project's schedule rather than when upstream publishes. So a contributor's environment is reproducible to the day and a user's environment is free to drift, which is the right way round for a library that people install as a dependency. It is also a lot of maintenance for one person, which is why the tree also carries a dependency update bot configuration.

## The badge has no accessible name in two of its three formats

The project asks you to add its badge to your readme and gives three formats. The Markdown form is a bare image link with nothing but a URL inside the brackets. The HTML form is an anchor containing an image and no text, and no alt attribute, so the link has no accessible name at all: a screen reader announces an unlabelled link. Only the reStructuredText form includes an alt attribute, and it is the odd one out because it is the only one where an alt attribute is idiomatic. There is a second inconsistency inside the same section. The Markdown and HTML badges point at a static image. The reStructuredText badge points at a dynamic endpoint whose URL contains the specification of the image encoded as a query parameter. So the three formats for the same badge are not three renderings of one asset; two of them are static and one is generated on request. There are then seven colour variations to choose from.

## Five ways to get a development environment and a markdown linter with an exception

The root of the repository offers five overlapping ways to get a working development setup: a dev container definition, a Gitpod configuration, a Devbox manifest with its own lock file, a direnv file, and a pinned Python version file. Any one of them would be a reasonable choice. Having all five means a contributor can use whichever their tooling already understands, at the cost of five places to update. The documentation has its own build system, with a MkDocs configuration, a hooks plugin and a Read the Docs configuration, so the site is generated rather than served from markdown in the repository. Two more details are small and specific. The readme itself is checked by a markdown linter, and it carries both a capture comment and an inline rule that disables one specific check, because the page uses inline HTML for the badges and the star history chart.

## Answers are validated by a model library and git is reached through a shell layer

Nothing on the page explains what the runtime dependencies are for, but the list describes the mechanism precisely. An interactive prompt library is the questionnaire you see in the terminal. A data validation library is why a question in the configuration file carries a type and a help string: the answers are validated against that schema rather than being passed around as strings. A shell execution library is the bridge to git, which is how a template is cloned and how its history is inspected. A path specification library handles gitignore-style filtering, which is how a template excludes files from the output. A templating engine and a filter pack for that engine provide the substitution and the YAML rendering used in the answers file. A syntax highlighter, a colour library for Windows terminals, a paths library for per-OS config directories, and a packaging version library for the version comparison in update logic. The console entry point is a class method rather than a function.

## The manifest names one author and the credits name five more

The manifest lists a single author with an email address, and the readme credits five people by name with a sentence each. The first credit is the important one: special thanks to the person who originally created the tool, with the note that the project would not exist without them. The second took over maintainership, promoted the project and laid the bases of what it is today. The remaining three are thanked for improvement work, for polishing edges and documentation, and for documentation, bug fixes and community work. Then a thank you to financial supporters. That is a coherent history for a project that has passed through at least three maintainers, and it is unusually well documented for one. It also sits against a detail worth noting: the root of the repository carries instructions aimed at coding agents, and a separate policy document governing their use, which is a more considered position than most projects have taken on the question.

## Conclusion

Copier suits a team that starts many similar services and wants their shared layout to be a repository that can change over time, rather than a one-shot scaffolding command. Four things to check first. Updating a generated project is opt-in per template, so a template that does not opt in gives you scaffolding and nothing else, and that distinction decides whether Copier replaces your scaffolding script. Git is a hard requirement at an explicitly stated minimum version, and the version string of the tool itself is derived from the repository rather than from a file. Development installs are pinned exactly, including type stub packages to dated builds, so a contributor's environment is reproducible while a user's is not. And the badge the project asks you to paste has no accessible name in the Markdown and HTML forms.

## FAQ

### What is a copier?

In this repository, a copier is a tool for rendering project templates. You write a template repository containing a YAML file of questions, one or more Jinja templates, and a generated answers file. Running the tool asks the questions and writes your project, substituting the answers into filenames and file contents, and it refuses to overwrite existing files unless told to.

### How do you say copier?

The repository does not discuss pronunciation; it is a single word used as the name of the package and the command. The package installs a console command of the same name, and the Python API is imported from the same package. The manifest gives one author and the credits name the person who originally created the tool plus four later contributors.

### how to install copier

Install Python 3.10 or newer and Git 2.27 or newer, then use one of four routes: a tool installer for the command line app, a plain package install or the conda-forge channel for library use, or the Homebrew formula. The Git requirement is not incidental: the package declares its version as dynamic and derives it from the repository, and it shells out to git to clone and inspect template sources.

### Can Copier update an existing project?

Only if the template opts in. The page lists two template goals: code scaffolding, which every template provides, and code lifecycle management, meaning consumers can update their projects when the template evolves, which not all templates allow. When updating is enabled, the tool relies on the answers file it wrote into the generated project to know what was asked previously, and it overwrites that file on each update.

### Is a copier also a printer?

Nothing in this repository connects the two. This project has nothing to do with office copying hardware; it is a template renderer whose name happens to be a common English word, which is why its search results are full of printers, copier paper and rental enquiries. It also points out that public templates can be browsed and tagged on GitHub through a topic, so the term has a second life inside the project as a label.

## Sources

- [copier-org/copier on GitHub](https://github.com/copier-org/copier)
- [License: MIT](https://github.com/copier-org/copier/blob/master/LICENSE)
- [Project website](https://copier.readthedocs.io/en/stable/)
- [README](https://github.com/copier-org/copier/blob/master/README.md)
- [Releases](https://github.com/copier-org/copier/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/copier-org-copier
