CLI tool to generate feature-based Vue.js architecture for any Vue.js project with TypeScript support
npm install vue-feature-scaffoldš A powerful CLI tool to generate feature-based Vue.js architecture for any Vue.js project with TypeScript support.
Optimized for Laravel + Inertia.js, but works with any Vue.js stack!
- šÆ Feature-based architecture - Self-contained, modular Vue components
- š Pure comment templates - Maximum flexibility with comprehensive examples
- š· TypeScript first - Full type safety out of the box
- ā” Framework agnostic - Works with Laravel, Nuxt, Vite, Vue CLI, or any Vue.js project
- šØ Customizable - Adapt generated code to your needs
- š”ļø Safe generation - Directory validation prevents accidents
This CLI works with any Vue.js project:
- ā
Laravel + Inertia.js (Primary focus)
- ā
Nuxt.js projects
- ā
Vite + Vue projects
- ā
Vue CLI projects
- ā
Standalone Vue.js apps
- ā
Quasar, Vuetify, or any Vue framework
- ā
Existing projects - Add features to any Vue codebase
``bashNavigate to your project
cd your-project
Or add to your project's
package.json for easier usage:`json
{
"scripts": {
"generate": "vue-feature-scaffold generate"
}
}
`Then use the npm script:
`bash
Generate features in your project
npm run generate users -- --dir resources/js/pages
npm run generate products -- --dir src/features
`š Generated Structure
$3
When you run
npx vue-feature-scaffold generate users --dir resources/js/pages, you get:`
resources/js/pages/
āāā users/
āāā Index.vue # Main feature entry component
āāā components/
ā āāā UsersTable.vue # Data table component
ā āāā UsersForm.vue # Create/edit form
āāā composables/
ā āāā useUsers.ts # State management & business logic
āāā services/
ā āāā usersApi.ts # API communication layer
āāā types.ts # TypeScript interfaces
`$3
When you add the
--store flag: npx vue-feature-scaffold generate users --dir resources/js/pages --store`
resources/js/pages/
āāā users/
āāā Index.vue # Main feature entry component
āāā components/
ā āāā UsersTable.vue # Data table component
ā āāā UsersForm.vue # Create/edit form
āāā stores/ # š Pinia store instead of composable
ā āāā useUsersStore.ts # Global state management with Pinia
āāā services/
ā āāā usersApi.ts # API communication layer
āāā types.ts # TypeScript interfaces
`$3
Index.vue - Main feature entry point- Flexible placeholder template with Inertia.js integration
- Includes breadcrumbs and layout components
- Contains commented examples for easy customization
- Adapt for lists, forms, dashboards, or any view type
components/UsersTable.vue - Data display component- Table component with sorting/filtering examples
- Receives data via props, emits events
- Pure presentation logic
components/UsersForm.vue - Create/edit form- Form component with validation patterns
- Handles create and update operations
- Loading states and error handling
composables/useUsers.ts - Business logic & state (Default)- Manages reactive state (users, loading, errors)
- CRUD operations using the API service
- Returns methods and state to components
- Component-local state - Each component gets its own instance
stores/useUsersStore.ts - Pinia Store (With --store flag)- Manages global shared state across all components
- Same CRUD operations as composables
- State persists across component navigation
- Perfect for authentication, shopping cart, notifications
- Requires:
npm install pinia
services/usersApi.ts - API communication layer- RESTful API functions (GET, POST, PUT, DELETE)
- Axios integration (easily swap with fetch)
- Typed request/response handling
types.ts - TypeScript definitions- Entity interfaces (User, CreateUserRequest, etc.)
- Request/response types
- Type-safe development
$3
| Option | Description | Default |
| -------------- | ---------------------------------------------------- | ------- |
|
--dir | Output directory (must exist) | src/ |
| --no-table | Skip table component generation | false |
| --no-form | Skip form component generation | false |
| --store | Generate Pinia store instead of composable (v0.2.0+) | false |
`$3
| Option | Description | Default |
| -------------- | --------------------------------- | ------- |
|
--dir | Output directory (must exist) | src/ |
| --no-table | Skip table component generation | false |
| --no-form | Skip form component generation | false |
$3
`bash
Basic feature generation (with composable)
npx vue-feature-scaffold generate users --dir resources/js/pages
npx vue-feature-scaffold generate job_publications --dir resources/js/pagesGenerate with Pinia store (global state)
npx vue-feature-scaffold generate auth --dir resources/js/pages --store
npx vue-feature-scaffold generate cart --dir resources/js/pages --storeSkip table component
npx vue-feature-scaffold generate dashboard --dir src/features --no-tableSkip form component
npx vue-feature-scaffold generate reports --dir src/features --no-formMinimal feature (no table, no form)
npx vue-feature-scaffold generate analytics --dir src/features --no-table --no-formPinia store without table/form
npx vue-feature-scaffold generate notifications --dir src/features --store --no-table --no-form
`$3
`bash
After adding "generate": "vue-feature-scaffold generate" to package.json
npm run generate users -- --dir resources/js/pages
npm run generate auth -- --dir resources/js/pages --store
npm run generate products -- --dir src/features --no-table
`šļø Composable vs Pinia Store
$3
Use composables when:
- ā
State is component-specific (not shared)
- ā
Each component needs its own independent data
- ā
Simple CRUD operations without global state needs
- ā
You want lightweight, no extra dependencies
Example: Product listings, user profiles, form handlers
What's new in recent versions:
-
v0.2.0 - NEW: Pinia store support with --store flag š
- v0.1.2 - Prevents duplicate feature generation (checks if folder exists)
- v0.1.1 - Preserves feature name format in folder structure
- v0.1.0 - Initial release with pure comment templates`typescript
// In any component
const { products, loading, fetchProducts } = useProducts()
// Each component calling useProducts() gets its own state
`$3
Use Pinia stores when:
- ā
State needs to be shared globally across components
- ā
State should persist during navigation
- ā
Multiple components need to access the same data
- ā
You need centralized state management (like Vuex)
Example: Authentication, shopping cart, notifications, user preferences
`bash
npx vue-feature-scaffold generate auth --dir resources/js/pages --store
`Generated:
stores/useAuthStore.ts`typescript
// In any component
const authStore = useAuthStore()
// All components share the same authStore state
`$3
| Feature | Composable (Default) | Pinia Store (
--store) |
| -------------------- | -------------------- | ----------------------- |
| State scope | Component-local | Global (shared) |
| Multiple instances | Yes | No (singleton) |
| Navigation persists | No | Yes |
| DevTools integration | Limited | Full support |
| Extra dependencies | None | pinia |
| Use case | Feature-specific | App-wide state |$3
If you use the
--store flag, install Pinia:`bash
npm install pinia
`Setup in Laravel + Inertia.js (
resources/js/app.ts):`typescript
import { createApp, h } from 'vue'
import { createInertiaApp } from '@inertiajs/vue3'
import { createPinia } from 'pinia'createInertiaApp({
resolve: (name) => require(
./pages/${name}.vue),
setup({ el, App, props, plugin }) {
createApp({ render: () => h(App, props) })
.use(plugin)
.use(createPinia()) // š Add this line
.mount(el)
}
})
`Usage in components:
`vue
` run generate products -- --dir src/features --no-table
`š Updating the Package
Keep your CLI up to date with the latest features and fixes:
`bash
Check current version
npm list vue-feature-scaffoldUpdate to latest version
npm update vue-feature-scaffoldOr install specific version
npm install vue-feature-scaffold@latestForce reinstall
npm uninstall vue-feature-scaffold
npm install vue-feature-scaffold
`What's new in recent versions:
-
v0.1.2 - Prevents duplicate feature generation (checks if folder exists)
- v0.1.1 - Preserves feature name format in folder structure
- v0.1.0 - Initial release with pure comment templatesThe CLI validates that the output directory exists before generating files. This prevents accidental file creation in wrong locations.
Generated files contain only comments with examples. This is intentional to give you maximum flexibility:
1. Open the generated file
2. Find the example that matches your needs
3. Uncomment it
4. Customize it for your use case
No opinionated code is forced on you!
Contributions are welcome! Please read CONTRIBUTING.md for details.
MIT License - see LICENSE file for details.
Built with ā¤ļø for developers who embrace:
- Feature-based architecture - Domain-driven, self-contained modules
- Vue.js ecosystem - Modern, reactive, and component-driven
- TypeScript - Type-safe development for better DX
- Laravel + Inertia.js - The perfect full-stack JavaScript experience
This tool was created to solve real-world challenges:
- Maintaining consistency across large Vue.js codebases
- Reducing boilerplate and setup time for new features
- Promoting best practices in component architecture
- Making TypeScript integration seamless and straightforward
Traditional folder-by-type structure:
```
src/
āāā components/ # All components mixed together
āāā composables/ # All composables mixed together
āāā services/ # All services mixed together
Problems:
- Hard to find related files
- Difficult to remove features
- Unclear ownership and boundaries
Feature-based structure (what this CLI generates):
```
src/
āāā users/ # Everything users-related
ā āāā components/
ā āāā composables/
ā āāā services/
āāā products/ # Everything products-related
āāā components/
āāā composables/
āāā services/
Benefits:
- ā
Clear feature boundaries
- ā
Easy to locate and modify code
- ā
Simple to delete entire features
- ā
Better team collaboration (feature ownership)
- ā
Scalable for large applications
---
Made with ā¤ļø for the Vue.js community
_Empowering developers to build maintainable, scalable Vue.js applications._
MIT