Production-Ready Express.js Project Scaffolding CLI
Generate complete, tested, and deployable Express applications in seconds with TypeScript/JavaScript support, authentication, databases, ORMs, and Docker integration.
- Features
- Quick Start
- Installation
- Usage
- CLI Options Reference
- Examples
- Generated Project Structure
- API Endpoints
- Configuration
- Docker Support
- Database & ORM Support
- Authentication System
- Testing & Validation
- Production Deployment
- Plugin System
- Troubleshooting
- Contributing
- License
| Feature | Description |
|---|---|
| Language Support | TypeScript (recommended) or JavaScript |
| Architecture Patterns | MVC (Model-View-Controller) structure |
| Authentication | JWT + Sessions + Refresh Tokens with bcrypt |
| Database Support | PostgreSQL and MySQL |
| ORM Integration | Prisma (recommended) or Sequelize |
| Docker Ready | Dockerfile + docker-compose with health checks |
| Automated Testing | 6+ built-in test suites run on generation |
- Health Endpoints -
/healthand/readyfor container orchestration - Graceful Shutdown - Proper SIGTERM/SIGINT handling with connection cleanup
- Session Support - Express-session configured (user configures store for production)
- Environment Configuration - Comprehensive .env setup
- Error Handling - Global error middleware with proper logging
- Security - CORS, bcrypt hashing, JWT validation, secure cookies
- Interactive Prompts - Guided project setup with validation
- Dry Run Mode - Preview project structure before creation
- Verbose Logging - Detailed output for debugging
- Rollback System - Automatic cleanup on errors
- Performance Optimized - Concurrent file operations and caching
- Cross-Platform - Works on Windows, macOS, and Linux
# Install globally
npm install -g scaffjs-cli
# Create a project interactively
scaffjs create
# Or create with specific options
scaffjs create my-api --ts --auth --pg --prisma --dockerAll
# Preview before creating
scaffjs create my-api --ts --dry-runnpm install -g scaffjs-clinpx scaffjs-cli create my-appgit clone https://github.com/SnoWed-29/Scaff-js.git
cd Scaff-js
npm install
npm run build
npm linkRun without arguments to enter guided setup:
scaffjs createYou'll be prompted for:
- Project name
- Language (TypeScript/JavaScript)
- Authentication (Yes/No)
- Database (None/PostgreSQL/MySQL)
- ORM (None/Prisma/Sequelize) - if database selected
- Docker (None/Dockerfile/Full Stack) - if database selected
Create projects directly with flags:
scaffjs create <project-name> [options]| Flag | Description |
|---|---|
--ts |
Use TypeScript with strict mode, type definitions, and build scripts |
--js |
Use JavaScript with ES6 modules |
| Flag | Description |
|---|---|
--auth |
Add JWT authentication with register, login, refresh, and logout endpoints |
| Flag | Description |
|---|---|
--pg |
PostgreSQL database connection |
--mysql |
MySQL database connection |
| Flag | Description |
|---|---|
--prisma |
Prisma ORM with schema, migrations, and type-safe queries |
--sequelize |
Sequelize ORM with models and automatic sync |
| Flag | Description |
|---|---|
--docker |
Generate Dockerfile only |
--dockerAll |
Generate Dockerfile + docker-compose.yml with database service |
| Flag | Description |
|---|---|
--dry-run |
Preview project structure without creating files |
--verbose |
Show detailed logs and test results during generation |
--no-install |
Skip automatic npm install |
--no-test |
Skip automatic testing after generation |
scaffjs create my-api --ts --auth --pg --prisma --dockerAllCreates a TypeScript API with:
- MVC architecture
- JWT authentication
- PostgreSQL database
- Prisma ORM
- Docker + Docker Compose setup
scaffjs create simple-api --jsCreates a basic JavaScript Express server with MVC structure.
scaffjs create enterprise-app --ts --auth --mysql --sequelize --dockerAllCreates a TypeScript API with:
- MVC architecture
- JWT authentication
- MySQL database
- Sequelize ORM
- Docker + Docker Compose setup
scaffjs create my-api --ts --auth --pg --prisma --dry-runShows the project structure without creating any files.
scaffjs create prototype --ts --no-install --no-testGenerates files only, skipping npm install and tests.
my-project/
├── src/
│ ├── controllers/
│ │ ├── hello.controller.ts
│ │ └── auth.controller.ts # if --auth
│ ├── models/
│ │ ├── User.ts # if --auth with Sequelize
│ │ └── Session.ts # if --auth with Sequelize
│ ├── routes/
│ │ ├── hello.routes.ts
│ │ └── auth.routes.ts # if --auth
│ ├── middleware/
│ │ └── auth.ts # if --auth
│ ├── database/
│ │ ├── connection.ts # if database without ORM
│ │ └── sequelize.ts # if --sequelize
│ ├── config/
│ │ └── index.ts
│ ├── utils/
│ │ └── jwt.ts # if --auth
│ └── index.ts
├── prisma/
│ ├── schema.prisma # if --prisma
│ └── migrations/ # if --prisma --dockerAll
├── dist/ # if TypeScript (compiled output)
├── package.json
├── tsconfig.json # if TypeScript
├── Dockerfile # if --docker or --dockerAll
├── docker-compose.yml # if --dockerAll
├── docker-entrypoint.sh # if --prisma --dockerAll
├── .dockerignore # if --docker or --dockerAll
├── .env.example
├── .gitignore
├── .scaffjs.json
└── README.md
| Method | Endpoint | Description | Response |
|---|---|---|---|
| GET | /health |
Liveness probe | { status: "ok", timestamp, uptime } |
| GET | /ready |
Readiness probe (checks DB) | { status: "ready", timestamp } |
| Method | Endpoint | Description | Response |
|---|---|---|---|
| GET | /hello |
Hello World test | { message: "Hello World!" } |
| Method | Endpoint | Description | Request Body | Response |
|---|---|---|---|---|
| POST | /auth/register |
Create account | { email, password, name } |
{ message, userId } |
| POST | /auth/login |
Get tokens | { email, password } |
{ accessToken, refreshToken, user } |
| POST | /auth/refresh |
Renew access token | { refreshToken } |
{ accessToken } |
| POST | /auth/logout |
Invalidate session | { refreshToken } |
{ message } |
Create a .env file from .env.example:
Linux/macOS:
cp .env.example .envWindows (PowerShell):
Copy-Item .env.example .envWindows (CMD):
copy .env.example .envPORT=3000
NODE_ENV=developmentDB_HOST=localhost
DB_PORT=5432 # PostgreSQL: 5432, MySQL: 3306
DB_NAME=my_database
DB_USER=postgres # or your database user
DB_PASSWORD=your_password
DATABASE_URL=postgresql://user:pass@localhost:5432/db # For PrismaJWT_SECRET=your-super-secret-jwt-key
JWT_REFRESH_SECRET=your-refresh-secret-key
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d
SESSION_SECRET=your-session-secretThe generated project uses in-memory session storage by default. For production, you should configure a persistent session store like Redis or MongoDB:
# Example: Redis session store (requires additional setup)
SESSION_STORE=redis
REDIS_URL=redis://localhost:6379
# Example: MongoDB session store (requires additional setup)
SESSION_STORE=mongo
MONGODB_URL=mongodb://localhost:27017/sessionsNote: You will need to install and configure the session store package (e.g., connect-redis, connect-mongo) in your generated project.
- Multi-stage builds for TypeScript (smaller production images)
- Alpine-based images (node:18-alpine)
- Health checks built-in
- Prisma client generation during build
- Production dependencies only in final image
When using --dockerAll:
- Application service on port 3000
- Database service (PostgreSQL or MySQL)
- Health checks with proper startup delays
- Volume persistence for database data
- Environment variables pre-configured
- Automatic migrations for Prisma
Docker Compose v2 (recommended):
docker compose up -dDocker Compose v1:
docker-compose up -dBuild and run separately:
docker compose build
docker compose up -dView logs:
docker compose logs -f appStop services:
docker compose downStop and remove volumes:
docker compose down -vSetup after generation:
# Generate Prisma client
npx prisma generate
# Run migrations (development)
npx prisma migrate dev
# Run migrations (production)
npx prisma migrate deploy
# Open Prisma Studio
npx prisma studioGenerated Schema (prisma/schema.prisma):
model User {
id String @id @default(uuid())
email String @unique
password String
name String?
refreshToken String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Session {
id String @id @default(uuid())
userId String
token String @unique @db.Text
expiresAt DateTime
createdAt DateTime @default(now())
}Notes:
sequelize.sync({ alter: true })only runs in development- Use migrations in production
- Models include User and Session (if auth enabled)
Production setup:
# Install Sequelize CLI
npm install -g sequelize-cli
# Run migrations
npx sequelize-cli db:migrate-
Registration: User provides email, password, and optional name. Password is hashed with bcrypt (10 salt rounds).
-
Login: User provides credentials. If valid, server returns:
accessToken(JWT, 15m expiry)refreshToken(JWT, 7d expiry)userobject
-
Protected Routes: Use the
authenticateTokenmiddleware:import { authenticateToken } from './middleware/auth'; router.get('/protected', authenticateToken, (req, res) => { // req.userId is available here });
-
Token Refresh: When access token expires, use refresh token to get a new access token.
-
Logout: Invalidates the refresh token in the database.
- Passwords hashed with bcrypt
- JWT tokens with configurable expiry
- Refresh tokens stored in database (can be revoked)
- HTTP-only secure cookies for sessions
- Session store ready for user configuration (Redis/MongoDB)
| Test | Description |
|---|---|
| Dependency Installation | Runs npm install (or npm ci if lock file exists) |
| Prisma Setup | Generates Prisma client |
| TypeScript Compilation | Builds the project |
| Project Structure | Validates required files exist |
| Docker Configuration | Checks Dockerfile and docker-compose.yml |
| Server Smoke Test | Starts server, hits /hello, verifies response, shuts down |
# Skip all tests
scaffjs create my-app --ts --no-install --no-test
# Skip only tests (still install)
scaffjs create my-app --ts --no-testscaffjs create my-app --ts --verboseShows detailed test results and performance metrics.
- Environment Variables: Set all secrets in
.env - Session Store: Configure Redis or MongoDB for sessions
- Database: Ensure DATABASE_URL is correct
- NODE_ENV: Set to
production - Migrations: Run
npx prisma migrate deployor Sequelize migrations
# Build for production
docker compose build
# Start services
docker compose up -d
# Check health
curl http://localhost:3000/health
curl http://localhost:3000/readyThe generated server handles:
SIGTERM- Kubernetes/Docker stop signalSIGINT- Ctrl+C
Shutdown process:
- Stop accepting new connections
- Complete in-flight requests
- Close database connections
- Exit cleanly (or force after 30s)
ScaffJs supports plugins for extending functionality.
plugins/
└── my-plugin/
├── plugin.json # Plugin manifest
├── generator.ts # Generator function
└── templates/ # Template files
{
"name": "my-plugin",
"version": "1.0.0",
"description": "My custom plugin",
"author": "Your Name",
"framework": "custom",
"generator": "./generator.ts",
"templates": "./templates"
}Plugins are automatically loaded from the plugins/ directory.
# Change port in .env
PORT=3001- Verify database is running
- Check credentials in
.env - Ensure correct port (PostgreSQL: 5432, MySQL: 3306)
- For Docker: wait for database health check
# Regenerate client
npx prisma generate
# Reset database (development only!)
npx prisma migrate reset
# Check schema validity
npx prisma validate# Check for errors
npm run build
# Clean and rebuild
rm -rf dist && npm run build# Rebuild images
docker compose build --no-cache
# View logs
docker compose logs -f
# Check container status
docker compose ps- Use PowerShell or Git Bash for better compatibility
- If
cpdoesn't work, useCopy-Item .env.example .env - For path issues, use forward slashes:
src/index.ts
Each generated project includes .scaffjs.json:
{
"projectName": "my-app",
"typescript": true,
"auth": true,
"database": "pg",
"orm": "prisma",
"docker": "dockerAll",
"createdAt": "2024-01-01T00:00:00.000Z",
"scaffjsVersion": "0.1.0"
}Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests
- Submit a pull request
See CONTRIBUTING.md for detailed guidelines.
git clone https://github.com/SnoWed-29/Scaff-js.git
cd Scaff-js
npm install
npm run build
npm link
# Make changes to src/
npm run build
# Test your changes
scaffjs create test-project --ts --dry-runMIT License - see LICENSE for details.
- Issues: GitHub Issues
- Documentation: This README
- Examples: See Examples section
- Contributing: See CONTRIBUTING.md
Built with care by the ScaffJs Team
Happy Scaffolding! 🚀