Templates
Templates are regular files in a directory. Both file names and file contents support Handlebars.js syntax for token replacement.
How Templates Are Resolved
Each path in the templates array is resolved individually. If a path points to a directory or glob
pattern containing multiple files, the first directory up the tree becomes the base path — files are
then copied recursively into output, preserving their relative structure.
In the examples below,
nameisAppNameandoutputissrc.
| Template path | Files found | Output |
|---|---|---|
./templates/{{ name }}.txt | ./templates/{{ name }}.txt | src/AppName.txt |
./templates/directory | outer/{{name}}.txt,outer2/inner/{{name}}.txt | src/outer/AppName.txt,src/outer2/inner/AppName.txt |
./templates/others/**/*.txt | outer/{{name}}.jpg,outer2/inner/{{name}}.txt | src/outer2/inner/AppName.txt |
Glob Patterns & Exclusions
Template paths support glob patterns and negation with !:
{
templates: ["templates/component/**", "!templates/component/README.md"]
}
Ignoring Files
Place a .scaffoldignore file in your template directory to exclude files. It works like
.gitignore — one pattern per line, # for comments.
# .scaffoldignore
*.log
node_modules
README.md
dist/**
The .scaffoldignore file itself is never copied to the output.
Patterns are matched against both the file's basename and its path relative to the template
directory, so README.md matches at any depth while dist/** only matches a dist directory at
the template root.
Token Replacement
Handlebars expressions like {{ name }} are replaced in both file names and file contents. The
name variable is always available — it's the name you pass when running the scaffold.
Any additional data from --data, -D, data config, or inputs is
also available.
npx simple-scaffold \
-t templates/component/{{name}}.jsx \
-o src/components \
MyComponent
This produces src/components/MyComponent.jsx, with all tokens inside the file replaced as well.
All standard Handlebars features work — {{#if}}, {{#each}}, {{#with}}, and more. See
Handlebars.js Language Features for details.
Built-in Helpers
Simple Scaffold includes helpers you can use in templates and file names. Helpers can also be
nested: {{ pascalCase (snakeCase name) }}.
Case Helpers
| Helper | Usage | my name becomes |
|---|---|---|
| (none) | {{ name }} | my name |
camelCase | {{ camelCase name }} | myName |
pascalCase | {{ pascalCase name }} | MyName |
snakeCase | {{ snakeCase name }} | my_name |
kebabCase | {{ kebabCase name }} | my-name |
hyphenCase | {{ hyphenCase name }} | my-name |
startCase | {{ startCase name }} | My Name |
upperCase | {{ upperCase name }} | MY NAME |
lowerCase | {{ lowerCase name }} | my name |
Date Helpers
Both now and date use date-fns format tokens.
| Helper | Example | Output |
|---|---|---|
now | {{ now "yyyy-MM-dd HH:mm" }} | 2042-01-01 15:00 |
now (with offset) | {{ now "yyyy-MM-dd HH:mm" -1 "hours" }} | 2042-01-01 14:00 |
date | {{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" }} | 2042-01-01 15:00 |
date (with offset) | {{ date "2042-01-01T15:00:00Z" "yyyy-MM-dd HH:mm" -1 "days" }} | 2041-12-31 15:00 |
date (from data) | {{ date myCustomDate "yyyy-MM-dd HH:mm" }} | (depends on data) |
Signatures:
now(format: string, offsetAmount?: number, offsetType?: "years" | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds")
date(date: string, format: string, offsetAmount?: number, offsetType?: "years" | "months" | "weeks" | "days" | "hours" | "minutes" | "seconds")
Custom Helpers
You can register custom Handlebars helpers via the helpers config option:
module.exports = {
component: {
templates: ["templates/component"],
output: "src/components",
helpers: {
shout: (text) => text.toUpperCase() + "!!!",
},
},
}
Then use in templates: {{ shout name }}.
All helpers (built-in and custom) are also available as values for subdirHelper (--subdir-helper
/ -H).
For more on Handlebars helpers, see the Handlebars.js docs.