@erwininteractive/mvc
v0.8.2
Published
A lightweight, full-featured MVC framework for Node.js with Express, Prisma, and EJS
Maintainers
Readme
@erwininteractive/mvc
A lightweight, full-featured MVC framework for Node.js 20+ built with TypeScript.
Features
- Express - Fast, unopinionated web framework for routing and middleware
- EJS Templating - Server-side templating with embedded JavaScript
- Prisma ORM - Type-safe database client (optional, PostgreSQL/MySQL/SQLite support)
- Redis Sessions - Scalable session management with connect-redis
- JWT Authentication - Secure token-based auth with bcrypt password hashing
- Session-Based Auth - Traditional session management with Express-Session
- WebAuthn (Passkeys) - Passwordless authentication with security keys (YubiKey, Touch ID, Face ID)
- Tailwind CSS - Modern, utility-first CSS framework (optional, included with
--with-tailwind) - Zod Validation - Type-safe form validation with TypeScript-first schemas
- CLI Tools - Scaffold apps with
--with-tailwind, generate models/controllers/resources - Flash Messages - Session-based success/error messages for forms
- Cookie Parser - Built-in cookie parsing for JWT and session support
- Helmet Security - HTTP header security middleware
- CORS Support - Cross-origin resource sharing middleware
- GitHub Actions CI - Automated testing with optional CI setup
Quick Start
npx @erwininteractive/mvc init myapp
cd myapp
npm run devVisit http://localhost:3000 - your app is running!
CLI Commands
Initialize a new app
# Basic app
npx @erwininteractive/mvc init myapp
# With Tailwind CSS
npx @erwininteractive/mvc init myapp --with-tailwind
# With database support (Prisma)
npx @erwininteractive/mvc init myapp --with-database
# With database + Tailwind
npx @erwininteractive/mvc init myapp --with-database --with-tailwind
# With GitHub Actions CI
npx @erwininteractive/mvc init myapp --with-ci
# Skip npm install (install manually later)
npx @erwininteractive/mvc init myapp --skip-installGenerate models
# Generate a Prisma model
npx erwinmvc generate model User
npx erwinmvc g model User
# Generate without running migration
npx erwinmvc generate model User --skip-migrateGenerate controllers
# Generate a CRUD controller
npx erwinmvc generate controller User
npx erwinmvc g controller User
# Generate without views
npx erwinmvc generate controller User --no-viewsGenerate resources (model + controller + views)
# Complete resource with all features
npx erwinmvc generate resource Post
npx erwinmvc g resource Post
# Skip specific parts
npx erwinmvc generate resource Post --skip-model
npx erwinmvc generate resource Post --skip-views
npx erwinmvc generate resource Post --skip-controller
# Skip database migration
npx erwinmvc generate resource Post --skip-migrate
# API-only resource (no views, JSON responses)
npx erwinmvc generate resource Post --api-onlyAuthentication commands
# Generate complete authentication system (login/register)
npx erwinmvc make:auth
npx erwinmvc ma
# Skip User model (use existing)
npx erwinmvc make:auth --without-model
# Only JWT (no sessions)
npx erwinmvc make:auth --jwt-only
# Only sessions (no JWT)
npx erwinmvc make:auth --session-onlyWebAuthn (Passkeys)
# Generate WebAuthn authentication (security key login)
npx erwinmvc webauthn
npx erwinmvc w
# Skip database migration
npx erwinmvc webauthn --skip-migrateList routes
# Show all defined routes
npx erwinmvc list:routes
npx erwinmvc lrProject Structure
myapp/
├── src/
│ ├── controllers/ # MVC controllers
│ ├── views/ # EJS templates
│ └── server.ts # App entry point
├── public/ # Static assets
│ └── dist/ # Compiled CSS (Tailwind)
├── prisma/ # Database (optional)
│ └── schema.prisma # Prisma schema
├── .github/ # CI workflows (optional)
├── package.json
├── tsconfig.json
├── tailwind.config.ts # Tailwind config (optional)
└── postcss.config.cjs # PostCSS config (optional)Database Setup
# Setup Prisma database
npx erwinmvc init myapp --with-database
cd myapp
# Edit .env with your DATABASE_URL
# DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
# Run migrations
npx prisma migrate dev --name init
# Generate Prisma client (auto-run by CLI)
npx prisma generateTailwind CSS Setup
npx erwinmvc init myapp --with-tailwind
cd myapp
# Configure content paths in tailwind.config.ts
# Edit src/assets/tailwind.css for custom styles
# Build CSS
npx tailwindcss -i ./src/assets/tailwind.css -o ./public/dist/tailwind.css --watchAuthentication
Session + JWT Auth
The make:auth command generates:
- User model with password hashing
- Register/login forms with Zod validation
- Session-based authentication
- JWT token generation for API access
- Password verification with bcrypt
- Flash messages for errors/success
WebAuthn (Passkeys)
The webauthn command generates:
- Passkey registration flow
- Passkey authentication flow
- User credential storage in database
- Security key support (YubiKey, Touch ID, Face ID)
Validation
Use Zod schemas for type-safe form validation:
import { z } from "zod";
import { validate } from "@erwininteractive/mvc";
const userSchema = z.object({
username: z.string().min(3),
email: z.string().email(),
password: z.string().min(8)
});
app.post("/users", validate(userSchema), async (req, res) => {
const user = req.validatedBody; // Type-safe validated data
// ...
});API Reference
Core Functions
createMvcApp(options)- Create Express app with views, static filesstartServer(app)- Start HTTP server on port 3000hashPassword(plain)- Hash password with bcryptverifyPassword(plain, hash)- Verify passwordsignToken(payload, expiresIn)- Sign JWT tokenverifyToken(token)- Verify and decode JWTauthenticate- Express middleware for JWT authenticationvalidate(schema, strategy)- Zod validation middleware
WebAuthn Functions
startRegistration(req, res)- Begin WebAuthn registrationcompleteRegistration(req, res)- Complete WebAuthn registrationstartAuthentication(req, res)- Begin WebAuthn logincompleteAuthentication(req, res)- Complete WebAuthn logingetRPConfig()- Get relying party configuration
Validation Helpers
getFieldErrors(error)- Extract field errors from Zod errorgetOldInput(req)- Get previously submitted form datagetErrors(req)- Get flash error messageshasFieldError(field, errors)- Check if field has errorsgetFieldError(field, errors)- Get error message for field
Environment Variables
Required for full functionality:
# Required
JWT_SECRET=your-secret-key-here
# Database (optional)
DATABASE_URL=postgresql://user:password@localhost:5432/mydb
# WebAuthn (optional, defaults to localhost)
WEBAUTHN_RP_ID=localhost
WEBAUTHN_RP_NAME=MyAppTesting
# Run all tests
npm test
# Run specific test file
npm test -- auth
npm test -- cli
npm test -- generators
# With coverage
npm run test -- --coverageProduction Build
# Build TypeScript and CLI
npm run build
# The app is ready for production deployment
# Server runs on port 3000License
MIT © Erwin Interactive
