Easy Pattern
Design a file/folder pattern once, then scaffold it anywhere in a few keystrokes.
Right-click a folder → Easy Pattern: Generate from Pattern → pick "React Component" → type user-card → get:
UserCard/
├── UserCard.tsx export default function UserCard() { … }
├── UserCard.test.tsx
└── index.ts export { default } from './UserCard';
Commands
| Command |
What it does |
Easy Pattern: Generate from Pattern |
Pick a pattern, answer the prompts, files appear |
Easy Pattern: Create New Pattern |
Wizard for a new pattern, then opens the JSON to fill in file bodies |
Easy Pattern: Create Pattern from Existing Folder |
Turn a folder you already built into a reusable pattern |
Easy Pattern: Edit / Duplicate / Delete Pattern |
Manage existing patterns |
An Easy Pattern view in the Explorer lists every pattern; clicking one generates from it.
Where patterns live
- Workspace —
.easy-pattern/*.json in the repo root. Commit them so the whole team gets the same scaffolding. Folder name configurable via easyPattern.patternsFolder.
- Global — extension storage, available in every workspace, only for you.
Both are plain JSON with a bundled schema, so editing them gives you autocomplete and validation.
{
"name": "React Component",
"description": "Folder + component + barrel + optional test",
"rootFolder": "{{name | pascal}}", // folder created inside the target (optional)
"variables": [
{ "name": "name", "label": "Component name", "type": "string" },
{ "name": "withTest", "label": "Add a test?", "type": "boolean", "default": true },
{ "name": "style", "type": "choice", "options": ["css", "scss", "none"] }
],
"files": [
{ "path": "{{name | pascal}}.tsx", "content": "export default function {{name | pascal}}() {}\n" },
{ "path": "index.ts", "content": "export { default } from './{{name | pascal}}';\n" },
{ "path": "{{name | pascal}}.test.tsx", "when": "withTest", "content": "…" },
{ "path": "__mocks__", "directory": true }
]
}
Variables
| Field |
Meaning |
name |
Identifier used in templates: {{name}} |
type |
string (input box), boolean (yes/no), choice (list of options) |
label / description |
Prompt title and hint |
default |
Pre-filled value, or the highlighted option for booleans |
pattern / patternError |
Regex validation for string inputs |
required |
Set false to allow an empty string |
Templating
{{ variable | filter | filter }} — filters chain left to right.
| Filter |
user card becomes |
pascal |
UserCard |
camel |
userCard |
kebab |
user-card |
snake |
user_card |
constant |
USER_CARD |
dot / path |
user.card / user/card |
title |
User Card |
lower / upper / capitalize / trim |
plain string ops |
plural / singular |
user cards / user card |
Conditionals work in both file bodies and file paths:
{{#if withTest}}…{{else}}…{{/if}}
{{#unless isPublic}}…{{/unless}}
The when field on a file entry decides whether it is created at all, and supports !, && and ||:
{ "path": "{{name|pascal}}.stories.tsx", "when": "withStories && !isInternal" }
An expression whose variable the pattern doesn't declare is left untouched, so captured Vue, Handlebars or Go templates survive generation intact.
Capturing a folder you already have
Right-click any folder → Create Pattern from Existing Folder. It reads the folder recursively, asks which word is the variable (defaults to the folder name), and replaces every casing of it — UserCard, userCard, user-card, USER_CARD — with the matching {{name | …}} expression. Binary files and the names listed in easyPattern.ignoreOnCapture are skipped.
Settings
| Setting |
Default |
Purpose |
easyPattern.patternsFolder |
.easy-pattern |
Where workspace patterns are stored |
easyPattern.openFirstFileAfterGenerate |
true |
Open the first generated file |
easyPattern.confirmOverwrite |
true |
Warn before overwriting existing files |
easyPattern.ignoreOnCapture |
node_modules, .git, dist, … |
Names skipped when capturing a folder |
Examples
examples/ holds ready-made patterns — copy one into .easy-pattern/ to try it:
mkdir -p .easy-pattern && cp examples/react-component.json .easy-pattern/
Development
npm install
npm run compile # or: npm run watch
Press F5 in VS Code to launch an Extension Development Host. Build a .vsix with npm run package.
Publishing
Before the first publish, three fields in package.json still need your details:
publisher — currently your-publisher-id. Create a publisher at
marketplace.visualstudio.com/manage and use that exact id.
repository / bugs / homepage — add them once the code lives in a Git repo, otherwise
packaging needs --allow-missing-repository and the Marketplace page shows no source link.
LICENSE — fill in the copyright holder.
Then:
npx @vscode/vsce login <your-publisher-id> # asks for an Azure DevOps Personal Access Token
npm run package # sanity-check the .vsix
npx @vscode/vsce publish # or: publish minor / publish 0.1.1
Install the local build without the Marketplace:
code --install-extension easy-pattern-0.1.0.vsix