create-initializer v1.3.0
NOTE
This is a forked and modified version of create-create-app. Modifications may be differ from the initial design of the original project so this will not be merged to the upstream and will be made into a seperate package.
Why?
- āļø Built-in License selector No need to manually add license things.
- š© Template engine Mustache will do things all.
- š Highly customizable Changable caveat text, and add extra cli options.
Table of contents
Quick Start
Let's create create-greet package in four steps.
1. npm create initializer
npm create initializer greetor if you use yarn, then run yarn create initializer greet

2. Edit templates
cd create-greet and edit files inside templates/default.
TypeScript
Run npm run build or yarn build to transpile TypeScript code into JavaScript.
3. Publish package to npm
Run npm publish or yarn publish to publish your create-greet app to npm.
4. PROFIT!
npm create greet ohayo
Template
Edit files inside templates/default. File names, directory names, and text files will be processed through Handlebars template engine to replace all template strings with respective value.
Built-in variables are:
{{name}}package name{{description}}package description{{author}}author name{{email}}author email{{contact}}author name formatted with{{name}} <{{email}}>if email given, otherwise{{name}}{{license}}package license (e.g.MIT){{year}}current year (e.g.2020)
Adding a template
Add new directory to the location defined in templateRoot; it will be accessible in --template flag (e.g. create-something <name> --template <template>).
Besides, set promptForTemplate true to explicitly ask users to pick a template in initialization phase, otherwise default will be used.
Helper functions
In the following example, we assume that variable name is create-react-app.
upper
Output text in UPPERCASE.
{{upper name}} becomes CREATE-REACT-APP.
lower
Output text in lowercase.
{{lower name}} becomes create-react-app.
capital
Output text in CapitalCase.
{{capital name}}becomesCreateReactApp{{capital name space=true}}becomesCreate React App.
camel
Output text in camelCase.
{{camel name}} becomes createReactApp.
snake
Output text in snake_case.
{{snake name}} becomes create_react_app.
kebab
Output text in kebab-case.
{{kebab name}} becomes create-react-app.
space
Replace all word separators with single space.
{{space name}} becomes create react app
uuid
Generates unique UUID string.
{{uuid}} // => a5df7100-da46-47a6-907e-afe861f48b39
{{upper (uuid)}} // => A5DF7100-DA46-47A6-907E-AFE861F48B39Config
You can find the app config in src/cli.js (or src/cli.ts if you chose typescript template).
import { resolve } from 'path';
import { create } from 'create-initializer';
create('create-greet', {
templateRoot: resolve(__dirname, '..', 'templates'),
defaultTemplate: 'my-template',
templatePrefix: 'template-',
extra: {
language: {
type: 'input',
describe: 'greeting language',
default: 'en',
prompt: 'if-no-arg',
},
},
modifyName: (name) => `package-prefix-${name}`,
after: ({ installNpmPackage }) => installNpmPackage('chalk'),
caveat: `Your app has been created successfully!`,
});templateRoot (required)
templateRoot set to path.resolve(__dirname, '../templates'). You can change it to whereever you want.
templatePrefix (default: <empty string>)
Set the prefix for template folder. Template prefix will be removed when displaying choices for the template.
For example: we have a template folder named template-awesome, we set templatePrefix to template-, then
create-something <name> --template awesomewill copy template-awesome to the destination dir.
promptForTemplate (default: false)
Ask users to choose a template to be used for initialization only if promptForTemplate is set true AND there's multiple templates found in templates/.
With promptForTemplate set false, users still can specify template via command-line flag --template:
create-something <name> --template <template>defaultTemplate (default: default)
Set the default template choice. Works both when promptForTemplate is true or false.
extra (default: undefined)
object | undefined
Extra options passed to the app. These options will be accessible as a cli option, interactive question, and template string. In this case, --language cli option and {{language}} template string will be available.
You can find all possible options in yargs-interactive documentation.
modifyName (default: undefined)
(name: string) => string | Promise<string>
Modify name property.
after (default: undefined)
(options: AfterHookOptions) => void
After hook script that runs after the initialization.
caveat (default: undefined)
string | ((options: AfterHookOptions) => string | void) | undefined
The caveat message will be shown after the entire process completed.
create('create-greet', {
caveat: 'Happy coding!',
});create('create-greet', {
caveat: ({ answers }) => `Run -> cd ${answers.name} && make`,
});create('create-greet', {
caveat: async ({ packageDir, answers }) => {
const { plugin } = answers;
await execa('npm', ['install', '--prefix', packageDir, '-S', plugin]);
console.log(`"${plugin}" has been added`);
},
});AfterHookOptions
{
// variables
packageDir: string;
templateDir: string;
year: number; // 2020
answers: {
name: string; // package name
description: string; // description
author: string; // John Doe
email: string; // john@example.com
contact: string; // John Doe <john@example.com>
license: string; // MIT
[key: string]: string | number | boolean | any[]; // any values defined in the `extra` field.
};
// functions
run: (command: string, options?: CommonOptions<string>) => ExecaChildProcess<string>; // run shell command in the package dir
addDependency: (packageName: string) => Promise<void>;
addDevDependency: (packageName: string) => Promise<void>;
removeDependency: (packageName: string) => Promise<void>;
}Contribution
PRs are always welcome!