Thank you for your interest in contributing! This document covers everything you need to get started.
- Code of Conduct
- How to Contribute
- Development Setup
- Project Structure
- Adding a New Template File
- Adding a New Feature Flag
- Commit Convention
- Pull Request Process
This project follows the Contributor Covenant. By participating you agree to abide by its terms. Please be respectful and constructive.
- Bug reports → open a GitHub Issue with reproduction steps
- Feature requests → open a GitHub Issue with your use case
- Code changes → fork → branch → PR (see below)
- Documentation → PRs for README / code comments are always welcome
- Node.js ≥ 18
- npm ≥ 9
git clone https://github.com/siddik-web/create-wp-plugin.git
cd create-wp-plugin
npm installnode bin/create-wp-plugin.js my-test-plugin
# or
npm startnpm testcreate-wp-plugin/
├── bin/
│ └── create-wp-plugin.js ← CLI entry point (Commander.js)
├── src/
│ ├── scaffold.js ← Main orchestrator — reads templates, writes files
│ ├── prompts.js ← Inquirer.js interactive prompts
│ ├── template-engine.js ← {{TOKEN}} replacement engine
│ ├── file-writer.js ← Disk writer utility
│ └── ui.js ← Chalk/Ora output helpers
├── src/templates/ ← All .tpl template files
│ ├── plugin-entry.php.tpl
│ ├── composer.json.tpl
│ ├── CLAUDE.md.tpl
│ ├── src/...
│ ├── tests/...
│ └── .claude/...
├── .github/
│ ├── workflows/ci.yml
│ └── ISSUE_TEMPLATE/
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE
└── README.md
- Create your template in
src/templates/with a.tplextension. - Use
{{TOKEN}}placeholders — seesrc/template-engine.jsfor the full token list. - Register the file in
src/scaffold.jsinside thescaffold()function:
writeFile(
outDir,
"src/my-new-file.php",
tpl("src/my-new-file.php.tpl"),
tokens,
);- If the file is optional (feature-gated), guard it with an
answers.has*boolean:
if (answers.hasMyFeature) {
writeFile(
outDir,
"src/my-feature.php",
tpl("src/my-feature.php.tpl"),
tokens,
);
}- Add the option to
bin/create-wp-plugin.js:
.option('--no-my-feature', 'Skip my feature')- Add a checkbox in
src/prompts.jsinside thefeaturesarray:
{ name: 'My new feature', value: 'myFeature', checked: cliOptions.myFeature !== false },- Add the boolean to the answers map at the bottom of
promptPluginDetails():
answers.hasMyFeature = features.includes("myFeature");- Add any new tokens to
buildTokens()insrc/template-engine.jsif needed.
| Token | Example output |
|---|---|
{{PLUGIN_SLUG}} |
my-awesome-plugin |
{{PLUGIN_NAME}} |
My Awesome Plugin |
{{PLUGIN_DESCRIPTION}} |
A production-ready plugin. |
{{NAMESPACE}} |
MyAwesomePlugin |
{{PREFIX}} |
myawesomeplugin |
{{PREFIX_UPPER}} |
MYAWESOMEPLUGIN |
{{TEXT_DOMAIN}} |
my-awesome-plugin |
{{CONST_VERSION}} |
MYAWESOMEPLUGIN_VERSION |
{{CONST_DIR}} |
MYAWESOMEPLUGIN_PLUGIN_DIR |
{{CONST_URL}} |
MYAWESOMEPLUGIN_PLUGIN_URL |
{{DB_TABLE}} |
myawesomeplugin_items |
{{MIN_WP}} |
6.0 |
{{MIN_PHP}} |
8.1 |
{{AUTHOR_NAME}} |
Jane Doe |
{{AUTHOR_URI}} |
https://janedoe.dev |
{{YEAR}} |
2026 |
This project uses Conventional Commits:
feat: add Gutenberg block scaffold option
fix: correct namespace in REST controller template
docs: add token reference to CONTRIBUTING
chore: bump chalk to 5.4.0
test: add template-engine unit tests
- Fork the repo and create a branch from
main:git checkout -b feat/my-feature
- Make your changes and ensure
npm testpasses. - Update
CHANGELOG.mdunder[Unreleased]. - Open a PR against
main— fill in the PR template. - A maintainer will review within a few days.
Please keep PRs focused — one feature or fix per PR makes review much easier.
Thank you for contributing! 🎉