Getting started
Install
engraft needs Node 22.22.2 or newer.
npm install -g @smartcompanion/engraft
Or run it without installing:
npx @smartcompanion/engraft --version
Your first customization
Start with a project that already works. Say it has a config.json:
{
"name": "DefaultApp",
"version": "1.0.0"
}
1. Declare what can be customized
Create engraft.template.yml. This is the file the project's maintainer owns —
it describes the customization surface, and it ships with the repository.
variables:
app_name:
description: Application name shown in the UI
default: DefaultApp
customizations:
- action: json_replace
file: config.json
replace:
- selector: $.name
variable: app_name
Two halves, and they stay separate on purpose:
variablesnames the things that can change, documents them, and records what the repository currently holds.customizationssays where each one lives. One entry per file, listing the selectors inside it.
2. Supply the values
Create engraft.values.yml. This is the consumer's file — one per brand,
customer or deployment, and it does not belong in the project repository.
app_name: MyApp
3. Apply
From the project directory:
engraft apply --template engraft.template.yml --values engraft.values.yml
config.json now reads:
{
"name": "MyApp",
"version": "1.0.0"
}
Nothing else moved. Run it again with a different values file and you get a different result from the same repository.
A more realistic template
Real customizations span several files and several kinds of file. Each action handles one format:
variables:
app_name:
description: Application name
default: DefaultApp
page_title:
description: Browser tab title
default: Default App
primary_color:
description: Brand colour, as a CSS hex value
default: "#ff0000"
logo:
description: Path to a replacement logo, relative to this values file
# No default: leave it out of the values file and the logo is untouched.
customizations:
- action: json_replace
file: package.json
replace:
- selector: $.name
variable: app_name
- action: html_replace
file: public/index.html
replace:
- selector: //title
variable: page_title
- action: regex_replace
file: src/theme.ts
replace:
- selector: '(PRIMARY_COLOR\s*=\s*)"(?<value>[^"]*)"'
variable: primary_color
- action: file_replace
file: public/logo.svg
variable: logo
app_name: acme-portal
page_title: Acme Portal
primary_color: "#0055ff"
logo: ./brand/acme-logo.svg
Each action is documented in full under Actions.
What to know before you run it on something you care about
- engraft writes to the current working directory.
file:paths in the template resolve against wherever you run it, not against the template's location. - An apply is all-or-nothing. Every action runs against a staging copy first; if one fails, your project is left exactly as it was. See Architecture.
- It edits in place, with no backup. Run it on a clean git working tree so
you can read the diff — and undo it with
git checkoutif you don't like it.
Next
- Concepts — the two-file model in detail
- Actions — the four actions and when to reach for each
- CLI reference