Skip to main content

index

Logo

GitHub | Documentation | NPM | casraf.dev

master build

Simple Scaffold is a file scaffolding tool. You define templates once, then generate files from them whenever you need — whether it's a single component or an entire app boilerplate.

Templates use Handlebars.js syntax, so you can inject data, loop over lists, use conditionals, and write custom helpers. It works as a CLI or as a Node.js library, and it doesn't care what kind of files you're generating.

Intro


Full documentation is available at chenasraf.github.io/simple-scaffold — including detailed guides on CLI usage, Node.js API, templates, configuration files, examples, and migration from v1/v2.

Table of Contents

Getting Started

Install

npm install -D simple-scaffold
# or use directly with npx
npx simple-scaffold

Initialize a Project

Run init to create a config file and an example template:

npx simple-scaffold init

This creates scaffold.config.js and templates/default/{{name}}.md. Now generate files:

npx simple-scaffold MyProject

One-off Usage (No Config)

Generate files from a template directory without a config file:

npx simple-scaffold -t templates/component -o src/components MyComponent

Configuration Files

Config files let you define reusable scaffold definitions. Simple Scaffold auto-detects config files in the current directory — no --config flag needed.

It searches for these files in order:

scaffold.config.{mjs,cjs,js,json}, scaffold.{mjs,cjs,js,json}, .scaffold.{mjs,cjs,js,json}

Example

// scaffold.config.js
module.exports = {
component: {
templates: ["templates/component"],
output: "src/components",
},
page: {
templates: ["templates/page"],
output: "src/pages",
subdir: true,
},
}

Then run:

npx simple-scaffold -k component MyComponent
npx simple-scaffold -k page Dashboard

Use the key default to skip the -k flag entirely.

Listing Available Templates

npx simple-scaffold list
npx simple-scaffold list -c path/to/config.js

Templates

Templates are regular files in a directory. Both file names and file contents support Handlebars syntax. Simple Scaffold preserves the directory structure of your template folder.

Example Template

templates/component/{{pascalCase name}}.tsx

// Created: {{ now 'yyyy-MM-dd' }}
import React from "react"

export default {{ pascalCase name }}: React.FC = (props) => {
return (
<div className="{{ camelCase name }}">{{ pascalCase name }} Component</div>
)
}

Running npx simple-scaffold -t templates/component -o src/components PageWrapper produces src/components/PageWrapper.tsx with all tokens replaced.

Glob Patterns & Exclusions

Template paths support globs and negation:

{
templates: ["templates/component/**", "!templates/component/README.md"]
}

.scaffoldignore

Place a .scaffoldignore file in your template directory to exclude files. It works like .gitignore — one pattern per line, # for comments.

Interactive Mode & Inputs

When running in a terminal, Simple Scaffold prompts for any missing required values (name, output, template key). Config files can also define inputs — custom fields that are prompted interactively:

module.exports = {
component: {
templates: ["templates/component"],
output: "src/components",
inputs: {
author: { type: "text", message: "Author name", required: true },
license: { type: "select", message: "License", options: ["MIT", "Apache-2.0", "GPL-3.0"] },
isPublic: { type: "confirm", message: "Public package?" },
priority: { type: "number", message: "Priority level", default: 1 },
},
},
}

Input types: text (default), select, confirm, number

Pre-fill inputs from the command line to skip prompts:

npx simple-scaffold -k component -D author=John -D license=MIT MyComponent

Remote Templates

Use templates from any Git repository:

# GitHub shorthand
npx simple-scaffold -g username/repo -k component MyComponent

# Full Git URL (GitLab, Bitbucket, etc.)
npx simple-scaffold -g https://gitlab.com/user/repo.git -k component MyComponent

The repository is cloned to a temporary directory, used, and cleaned up automatically.

CLI Reference

Commands

CommandDescription
[name]Generate files from a template (default)
initCreate config file and example template
list / lsList available template keys in a config

Options

FlagShortDescriptionDefault
--config-cPath to config file or directoryauto-detect
--git-gGit URL or GitHub shorthand
--key-kTemplate key from configdefault
--output-oOutput directory
--templates-tTemplate file paths or globs
--data-dCustom JSON data
--append-data-DKey-value data (key=string, key:=raw)
--subdir/--no-subdir-s/-SCreate parent directory with input namefalse
--subdir-helper-HHelper to transform subdir name
--overwrite/--no-overwrite-w/-WOverwrite existing filesfalse
--dry-run-drPreview output without writing filesfalse
--before-write-BScript to run before each file is written
--after-scaffold-AShell command to run after scaffolding
--quiet-qSuppress output
--log-level-lLog level (none, debug, info, warn, error)info
--version-vShow version
--help-hShow help

Node.js API

import Scaffold from "simple-scaffold"

// Basic usage
const scaffold = new Scaffold({
name: "MyComponent",
templates: ["templates/component"],
output: "src/components",
})
await scaffold.run()

// Load from config file
const scaffold = await Scaffold.fromConfig("scaffold.config.js", {
key: "component",
name: "MyComponent",
})
await scaffold.run()

Config Options

OptionTypeDescription
namestringName for generated files (required)
templatesstring[]Template paths or globs (required)
outputstring | FunctionOutput directory or per-file function
dataRecord<string, unknown>Custom template data
inputsRecord<string, Input>Interactive input definitions
helpersRecord<string, Function>Custom Handlebars helpers
subdirbooleanCreate parent directory with name
subdirHelperstringHelper for subdir name transformation
overwriteboolean | FunctionOverwrite existing files
dryRunbooleanPreview without writing
logLevelstringLog verbosity
beforeWriteFunctionAsync hook before each file write
afterScaffoldFunction | stringHook after all files are written

Built-in Helpers

All helpers work in both file names and file contents.

Case Helpers

HelperExample InputOutput
camelCasemy namemyName
pascalCasemy nameMyName
snakeCasemy namemy_name
kebabCasemy namemy-name
hyphenCasemy namemy-name
startCasemy nameMy Name
upperCasemy nameMY NAME
lowerCaseMy Namemy name

Date Helpers

{{now "yyyy-MM-dd"}}
{{now "yyyy-MM-dd HH:mm" -1 "hours"}}
{{date myDateVar "yyyy-MM-dd"}}
{{date "2077-01-01T00:00:00Z" "yyyy-MM-dd" 7 "days"}}

Custom Helpers

Add your own via config:

module.exports = {
component: {
templates: ["templates/component"],
output: "src/components",
helpers: {
shout: (str) => str.toUpperCase() + "!!!",
},
},
}

Contributing

I am developing this package on my free time, so any support, whether code, issues, or just stars is very helpful to sustaining its life. If you are feeling incredibly generous and would like to donate just a small amount to help sustain this project, I would be very very thankful!

Buy Me a Coffee at ko-fi.com

I welcome any issues or pull requests on GitHub. If you find a bug, or would like a new feature, don't hesitate to open an appropriate issue and I will do my best to reply promptly.

If you are a developer and want to contribute code, here are some starting tips:

  1. Fork this repository
  2. Run pnpm install
  3. Run pnpm dev to start file watch mode
  4. Make any changes you would like
  5. Create tests for your changes
  6. Update the relevant documentation (readme, code comments, type comments)
  7. Create a PR on upstream

Some tips on getting around the code:

  • Use pnpm cmd to use the CLI feature of Simple Scaffold from within the root directory, enabling you to test different behaviors. See pnpm cmd -h for more information.
  • Use pnpm test to run tests
  • Use pnpm docs:build to build the documentation once
  • Use pnpm docs:watch to start docs in watch mode
  • Use pnpm build to build the output