Project Next StepA VS Code extension that supports two code-generation experiences:
Table of Contents
Requirements
InstallationFrom source (development)
Then press As a
|
| Intent | Folder Location | Filename Keyword | Extensions |
|---|---|---|---|
CREATE_COMPONENT |
components/ |
card, button, input, modal, avatar, list, item, header, footer, sidebar, nav | .tsx, .jsx |
CREATE_PAGE |
pages/, app/ |
— | .tsx, .jsx |
CREATE_HOOK |
hooks/ |
use (e.g. useAuth.ts) |
.ts, .tsx, .js |
CREATE_SERVICE |
services/ |
service | all source |
CREATE_CONTROLLER |
controllers/ |
controller | all source |
CREATE_ROUTE |
routes/, router/ |
route, router | all source |
CREATE_MODEL |
models/, entities/ |
model, schema, entity | all source |
CREATE_API |
api/, apis/ |
api | all source |
CREATE_FORM |
forms/ |
form | .tsx, .jsx |
CREATE_TEST |
tests/, test/, __tests__/, spec/ |
.test, .spec, test., spec., _test | all source |
CREATE_MIDDLEWARE |
middleware/, middlewares/ |
middleware, auth | all source |
CREATE_TYPES |
types/, interfaces/ |
types, interface, typings | .ts, .d.ts |
CREATE_FEATURE |
features/ |
— | all source |
"all source" =
.ts, .tsx, .js, .jsx, .py, .go, .rb, .php, .java, .cs
The src/ prefix is always matched too (e.g. src/components/, src/routes/). Framework-specific paths like app/controllers/ (Rails) and lib/services/ (Go/Node) are also recognized.
Convention detection
Auto-suggestions inspect your existing files and match their style:
| Convention | What It Copies |
|---|---|
| Naming | PascalCase, camelCase, kebab-case, snake_case |
| Exports | default, named, module.exports |
| Imports | ESM (import/export) vs CommonJS (require) |
| Components | Functional vs class vs arrow function |
| Style | Single/double quotes, semicolons, indentation |
Feature 2: Template Wizard
A guided, step-by-step wizard for scaffolding complete, multi-file folders. This is the recommended way to generate production-ready boilerplate.
Flow
Select Category → Select Template → Answer Questions → Preview → Generate
- Category — auto-detected from your project (React, Express, Python, etc.)
- Template — choose what to scaffold
- Questions — only the inputs relevant to that template (name, props, fields, options)
- Preview — a summary of every file to be created
- Confirm — all files are written to a new folder automatically
Supported question types:
| Type | UI | Example |
|---|---|---|
input |
Text input | Component name |
quickpick |
Dropdown list | CRUD operations (all / read / custom) |
confirm |
Yes / No | Include loading state? |
Questions support conditional logic — a question is skipped when it doesn't apply based on earlier answers.
Available templates by language
| Language | Templates | Default folder |
|---|---|---|
| React | Basic Component, Page, Form, Modal, Card, Table, Layout, API Data Component, Custom Hook, Context | components/, pages/, forms/, hooks/, contexts/ |
| Express | Controller, Route, Service, Middleware, Model | controllers/, routes/, services/, middleware/, models/ |
| Python | Class, API Endpoint, Service, Model | models/, api/, services/ |
| Java | Controller, Service, Repository, Entity | controllers/, services/, repositories/, models/ |
| C# | Controller, Service, Model | Controllers/, Services/, Models/ |
| Go | Handler, Service, Model | handlers/, services/, models/ |
| Ruby | Controller, Service, Model | app/controllers/, app/services/, app/models/ |
| PHP | Controller, Service, Model | app/Http/Controllers/, app/Services/, app/Models/ |
Multi-file generation
Each template creates a folder containing related files. Only the files you select (via answers) are generated.
Example — a React Basic Component named UserCard might produce:
components/
└── UserCard/
├── UserCard.tsx # the component
├── index.ts # barrel export
├── UserCard.module.css # styles
└── UserCard.test.tsx # tests (optional)
Example — an Express Controller named User might produce:
controllers/
└── User/
├── user.controller.ts
├── user.types.ts
└── user.controller.test.ts
Naming convention: file/folder names follow the project's language convention. PascalCase for React/C#/Java/(SOME), kebab-case for Go, snake_case for Python/Ruby, etc.
Editing existing templates
All templates live in src/wizard/templates/<language>/. See TEMPLATES.md for a full reference on structure, questions, and how to add your own.
Supported Languages & Frameworks
| Language | Framework | Auto-Suggest | Wizard |
|---|---|---|---|
| TypeScript / JavaScript | React | ✅ | ✅ |
| TypeScript / JavaScript | Express | ✅ | ✅ |
| Python | Flask / FastAPI / Django | ✅ | ✅ |
| Go | Gin | ✅ | ✅ |
| Ruby | Rails | ✅ | ✅ |
| PHP | Laravel | ✅ | ✅ |
| Java | Spring | ✅ | ✅ |
| C# | .NET | ✅ | ✅ |
Language detection
Language is detected from config files (checked in order):
| Config File | Detected Language |
|---|---|
tsconfig.json |
TypeScript |
jsconfig.json |
JavaScript |
go.mod |
Go |
Gemfile / Rakefile |
Ruby |
manage.py / requirements.txt |
Python |
composer.json |
PHP |
pom.xml / build.gradle |
Java |
*.sln / *.csproj |
C# |
If none are found, the extension counts source files by extension and picks the most common language.
Configuration
These settings are available under Settings → Extensions → Project Next Step or in .vscode/settings.json:
| Setting | Default | Description |
|---|---|---|
projectNextStep.enabled |
true |
Enable or disable auto-suggestions |
projectNextStep.minConfidence |
0.6 |
Minimum confidence (0.1–1.0) to show an auto-suggestion |
projectNextStep.cooldownMinutes |
60 |
Minutes to suppress an auto-suggestion after it's ignored |
projectNextStep.debounceMs |
800 |
Milliseconds to wait after a file event before analyzing |
Example .vscode/settings.json:
{
"projectNextStep.enabled": true,
"projectNextStep.minConfidence": 0.7,
"projectNextStep.cooldownMinutes": 30,
"projectNextStep.debounceMs": 500
}
Configuration is not hot-reloaded for every change; the extension re-reads it on file events and at startup.
Commands
| Command | ID | Description |
|---|---|---|
| Project Next Step: Suggest Next Step | projectNextStep.trigger |
Manually trigger an auto-suggestion for the active file |
| Project Next Step: New Wizard | projectNextStep.wizard |
Launch the template wizard |
Development
Prerequisites
- Node.js 16+
- VS Code
Setup
npm install
npm run compile
Scripts
| Script | Description |
|---|---|
npm run compile |
Compile TypeScript once |
npm run watch |
Auto-compile on every save |
npm test |
Run unit tests (note: see Troubleshooting) |
npm run lint |
Lint src/ with ESLint |
npm run vscode:prepublish |
Compile before packaging |
Test the extension (F5)
- Press F5 in VS Code (requires a
.vscode/launch.json— auto-created by the VS Code extension template, or add one manually) - A new Extension Development Host window opens with the extension loaded
- Create a file in the debug workspace to test auto-suggestions, or run the wizard command
A minimal .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Run Extension",
"type": "extensionHost",
"request": "launch",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"outFiles": ["${workspaceFolder}/out/**/*.js"],
"preLaunchTask": "npm: watch"
}
]
}
Debug logging
Two options:
console.log(...)→ appears in the Debug Console of the F5 window.- Output channel →
outputChannel?.appendLine(...)→ appears in VS Code's Output panel (select "Project Next Step" from the dropdown).
The output channel is declared in src/extension.ts. To log from modules that don't have access to it, use console.log.
Troubleshooting
"No templates available for this project type"
- The wizard filters templates by your project's detected language. If the language can't be detected (e.g. an empty workspace), try adding a recognized config file (
package.json,tsconfig.json,go.mod, etc.). - If your project has no framework detected, all templates for the detected language are shown — pick the right category manually.
TypeScript compilation fails
npm install
npm run compile
Ensure node_modules is installed and you're on the matching Node version.
npm test fails with "ERR_MODULE_NOT_FOUND"
This is a known pre-existing issue with ESM module resolution in the mocha test runner for the framework imports (src/frameworks/*). It is unrelated to the wizard. The TypeScript compilation (npm run compile) passes cleanly. Tracked separately from the wizard feature.
Auto-suggestion doesn't fire
- Check
projectNextStep.enabledistrue. - The file must be in a recognized directory/name matching an intent (see the trigger table).
- The suggestion confidence must exceed
minConfidence. - A cooldown may be suppressing repeats for the same file.
Architecture
The extension has two independent but complementary subsystems:
src/
├── extension.ts # Entry point, VS Code event wiring, debounce, command registration
├── types.ts # Shared type definitions (Language, Convention, etc.)
├── utils.ts # Naming helpers, extension↔language mapping
│
├── context/
│ ├── ProjectScanner.ts # Scans workspace, detects framework & language
│ ├── FileAnalyzer.ts # Extracts metadata from a created file
│ └── ConventionAnalyzer.ts # Detects coding conventions from existing files
│
├── intent/
│ ├── IntentEngine.ts # Combines signals to pick the best intent
│ └── IntentRules.ts # Rule definitions for each intent type
│
├── generation/
│ ├── BoilerplateEngine.ts # Auto-suggest: orchestrates providers + template rendering
│ └── TemplateEngine.ts # Simple {{variable}} template renderer
│
├── suggestions/
│ ├── SuggestionEngine.ts # Auto-suggest pipeline: scan → detect → generate → suggest
│ └── SuggestionState.ts # Cooldown & dismiss tracking per file
│
├── ui/
│ └── SuggestionPanel.ts # QuickPick-based auto-suggestion UI
│
├── wizard/ # Wizard subsystem (independent)
│ ├── WizardEngine.ts # Orchestrator: category → template → questions → preview → write
│ ├── WizardTypes.ts # All wizard-specific types (see TEMPLATES.md)
│ ├── TemplateRegistry.ts # Central registry; filters templates by language/framework
│ ├── FileGenerator.ts # Creates folders and writes files to disk
│ ├── questions/
│ │ └── QuestionBuilder.ts # Reusable question factories
│ └── templates/ # One file per template, grouped by language
│ ├── react/ # 10 templates
│ ├── express/ # 5 templates
│ ├── python/ # 4 templates
│ ├── java/ # 4 templates
│ ├── csharp/ # 3 templates
│ ├── go/ # 3 templates
│ ├── ruby/ # 3 templates
│ └── php/ # 3 templates
│
└── frameworks/ # Auto-suggest providers (one per language/framework)
├── FrameworkProvider.ts # LanguageProvider interface + helpers
├── ReactTypeScript.ts
├── NodeExpress.ts
├── Python.ts
├── GoProvider.ts
├── RubyProvider.ts
├── PhpProvider.ts
├── JavaProvider.ts
└── CSharpProvider.ts
Key design principle: the auto-suggest subsystem (suggestions/, generation/, frameworks/) and the wizard subsystem (wizard/) are independent. They share only types.ts, utils.ts, and the context detectors. You can modify or extend one without touching the other.
Contributing
See CONTRIBUTING.md for coding standards, testing, and the PR process. See TEMPLATES.md for how to add or modify wizard templates.
License
MIT — see LICENSE.