New Template Guide
Learn how to add new project templates to the Compose CLI so contributors can scaffold diamonds and example projects consistently.
When to Add a New Template
Add a new CLI template when you want to:
- Showcase a new pattern (e.g. a new facet layout or diamond configuration).
- Support a new framework variant (e.g. a different Hardhat layout).
- Provide an opinionated starter (e.g. ERC‑721, ERC‑20, or example applications).
Templates should demonstrate one clear pattern. Avoid shipping large demo apps or unnecessary dependencies.
Overview of the Template System
Templates live in the CLI package under cli/src/templates. Each template has:
- A template id – top‑level folder and manifest.
- One or more variants – concrete projects for a framework / language combo.
- A generated registry –
src/config/templates.json, built from all manifests.
Prerequisites
From the cli directory:
npm install
npm run build:templates
You also need:
- Node.js 20 or higher.
- A basic understanding of Foundry and/or Hardhat layouts. (You can always refer to the default template)
Test the CLI locally
npm link
This will create a symlink to the CLI in your global node_modules directory.
You can then test the CLI by running:
compose --help
1. Create the Template Folder
Templates are grouped by template id:
- Root folder:
cli/src/templates/<template-id> - Example:
cli/src/templates/erc721
Choose an id that is:
- Short and descriptive, e.g.
erc721,erc20,example-counter. - Stable, because users reference it via
--template <template-id>.
2. Add template.json
Create a manifest at:
cli/src/templates/<template-id>/template.json
This file declares:
- id – must match the folder name and CLI
--templatevalue. - name – human‑readable label shown in
compose templates. - description – short explanation of what the template includes.
- variants – list of variant ids (see next section).
- compatibility.frameworks – supported frameworks (
foundry,hardhat).
Example:
{
"id": "erc721",
"name": "ERC-721 Diamond",
"description": "Diamond project with an ERC-721 facet",
"variants": [
"erc721-foundry",
"erc721-hardhat-minimal"
],
"compatibility": {
"frameworks": ["foundry", "hardhat"]
}
}
The npm run build:templates script validates all template.json files and regenerates the registry. If something is wrong, the build will fail.
3. Create Variant Directories
Each variant id maps to a concrete folder on disk:
- Foundry
- Variant id:
<template-id>-foundry - Path:
cli/src/templates/<template-id>/foundry
- Variant id:
- Hardhat (framework‑only)
- Variant id:
<template-id>-hardhat - Path:
cli/src/templates/<template-id>/hardhat
- Variant id:
- Hardhat with project type (language/layout)
- Variant id:
<template-id>-hardhat-<project-type> - Path:
cli/src/templates/<template-id>/hardhat/ts/<project-type>for TypeScript - Path:
cli/src/templates/<template-id>/hardhat/js/<project-type>for JavaScript
- Variant id:
Inside each variant directory, add the full scaffolded project:
- Contracts, config files, scripts, tests, etc.
- Any
READMEor notes specific to that template.
The CLI knows the language from the variant path. For Foundry templates, only the framework is set.
4. Regenerate the Template Registry
Whenever you add or modify templates, rebuild the registry from the cli directory by running:
npm run build:templates
- Scans all
src/templates/**/template.jsonmanifests. - Validates ids, variants, and compatibility fields.
- Regenerates
src/config/templates.jsonused by the CLI.
If the command fails, fix the manifest or folder layout until the build succeeds.
5. Verify Your Template
First, list templates via the local CLI:
node index.js templates
Check that:
- Your template id appears in the list.
- All variants are listed with the expected framework and language.
Then scaffold a project using your new template:
compose init \
--name my-test-project \
--template <template-id> \
--framework <framework> \
--yes
From inside the generated project, run the usual framework commands:
- For Foundry:
forge build,forge test - For Hardhat:
npm test,npx hardhat test, etc.
Review Checklist
Before opening a pull request:
- Template structure
cli/src/templates/<template-id>exists.template.jsonis valid and matches the folder name.- All variant ids map to real directories.
- Registry & CLI
npm run build:templatespasses.node index.js templatesshows the new template and variants.node index.js init ...successfully scaffolds a project.
- Quality
- Template files follow existing code style and project layout.
- Dependencies are minimal and justified.
- Any README or comments clearly explain what the template demonstrates.