@3mo.tony/unc.js
v1.0.4
Published
Unc.js — light CLI to scaffold Express backends (JS/TS, Mongoose/Prisma/Sequelize)
Downloads
266
Maintainers
Readme
Unc.js
Forge production-ready backends in seconds — layered architecture, your stack, your ORM.
Unc.js (unc on the command line, like Nest’s nest) scaffolds Express apps (JS or TS), wires Mongoose / Prisma / Sequelize, and generates full CRUD modules so you ship features instead of folder plumbing.
- Bootstrap a new API with optional ESLint, Prettier, and Husky
- Choose your language — JavaScript or TypeScript (Express)
- Pick your ORM — Mongoose, Prisma, or Sequelize
- Ship modules fast — model, service, controller, routes, schemas, DTOs in one command
- Commit helpers included —
commit-and-push.bat/commit-and-push.shformat, lint, commit, and publish the branch if it is not on the remote yet
Why use it?
Building a new backend usually means copying the same boilerplate over and over: folder structure, path aliases, linting, database loader, service base class, and CRUD files for each entity.
unc automates that workflow so you can focus on business logic instead of file plumbing.
| Step | What you run | What you get |
|---|---|---|
| 1 | unc init my-api | Full project scaffold + BaseService + ORM setup |
| 2 | unc generate module events | Model, service, controller, routes, schemas, DTOs |
Installation
Global install (recommended for daily use)
npm install -g @3mo.tony/unc.jsOr without a global install:
npx @3mo.tony/unc.js init my-apiLocal development
git clone <repo-url>
cd unc.js
npm install
npm run build
npm linkAfter linking, the unc command is available globally on your machine (same idea as Nest’s nest CLI).
Quick start
# 1. Interactive init (prompts for language, ORM, tooling — then npm install)
unc init events-api
cd events-api
# 2. Generate a full CRUD module (BaseService is created during init)
unc generate module events --fields "name:string,startsAt:date,description:string:optional"
# 3. Start developing
npm run devNon-interactive example:
unc init events-api --language ts --orm mongoose --eslint --prettier --huskyCommit helpers (included in generated apps)
After init, every project includes:
| File | Platform |
|------|----------|
| commit-and-push.bat | Windows |
| commit-and-push.sh | macOS / Linux |
They run format → lint:fix → git add → commit → push. If the branch has no upstream, they publish it with git push -u origin HEAD.
# Windows
commit-and-push.bat "feat: add events module"
commit-and-push.bat "feat: add events module" -d "Optional longer description"
# Unix
chmod +x commit-and-push.sh
./commit-and-push.sh "feat: add events module"
./commit-and-push.sh "feat: add events module" -d "Optional longer description"Generated project structure
When you run init, the CLI creates a project based on the Unc.js layout:
src/
├── adapters/ # External service adapters
├── combined-services/ # Cross-model service orchestration
├── config/ # Environment and app configuration
├── constants/ # Endpoints, tables, messages
├── contracts/ # Interfaces and DTO contracts
├── controllers/ # Request handlers
├── interceptors/ # Third-party API interceptors
├── loaders/ # Express app + database bootstrapping
├── locales/ # i18n translation files
├── middlewares/ # Express middlewares
├── models/ # Database models
├── processes/ # Cron jobs and background tasks
├── routes/ # API route definitions
├── schemas/ # Zod validation schemas
├── services/ # Business logic layer
├── swagger/ # OpenAPI definitions
├── types/ # Enums and DTO types
├── utils/ # Shared utilities
└── views/ # View templatesThe scaffold also includes:
- TypeScript with strict mode and path aliases (
@services,@controllers,@schema, etc.) - ESLint v9 flat config + Prettier
- Express server with
/api/v1routing - Zod validation middleware
- A
.uncjs.jsonconfig file that records your ORM choice commit-and-push.bat/commit-and-push.sh— one-shot format → lint → commit → push (creates remote tracking branch when missing)
How module generation works
Running unc generate module events creates a full vertical slice for the events resource:
New files
| File | Description |
|---|---|
| src/models/events.model.ts | Sequelize model or Mongoose schema |
| src/services/events.service.ts | Service class extending BaseService |
| src/controllers/events.controller.ts | CRUD controller (create, getAll, getOne, update, delete) |
| src/routes/events.routes.ts | Express router with validation |
| src/contracts/events.interface.ts | Entity interface and create DTO |
| src/schemas/events.schema.ts | Zod create/update schemas |
| src/types/dtos/events/*.dto.ts | Request/response TypeScript types |
Updated files
The CLI also patches existing barrel files and constants:
src/models/index.ts— exports the new modelsrc/services/index.ts— exports the new servicesrc/controllers/index.ts— exports the new controllersrc/contracts/index.ts— exports the new interfacesrc/schemas/index.ts— exports the new schemasrc/types/dtos/index.ts— exports the new DTO foldersrc/constants/endpoints.ts— addsEVENTStoGENERAL_ENDPOINTSandEVENTS_ENDPOINTSsrc/constants/tables.ts— addsEventsentry (Sequelize only)src/routes/index.ts— imports and mounts the new router
Service inheritance
Every generated service extends the ORM-specific BaseService:
class EventsService extends BaseService<IEventsModel, EventCreateDTO> {
constructor() {
super(EventsModel, Tables.Events)
}
}You can add custom methods to the generated service file without losing the base CRUD behavior.
ORM support
Sequelize (PostgreSQL)
- Selected with
--orm sequelize(default) - Adds
sequelize,pg, andpg-hstoredependencies - Generates Sequelize models using
DataTypes - Base service uses
ModelStatic, transactions, andincludefor population - Table names are registered in
src/constants/tables.ts
Mongoose (MongoDB)
- Selected with
--orm mongoose - Adds
mongoosedependency - Generates Mongoose schemas with
Schemaandmodel - Base service uses
FilterQuery,find,findOneAndUpdate, etc. - Controllers use
_idfor lookups instead of numericid
The ORM is stored in .uncjs.json at the project root:
{
"version": "1.0.4",
"language": "ts",
"framework": "express",
"orm": "mongoose",
"eslint": true,
"prettier": true,
"husky": false
}All generate commands read this file to pick the correct templates.
Field definition syntax
When generating a module, define model fields with --fields:
unc generate module products --fields name:string,price:number,isActive:boolean,expiresAt:date| Type | Maps to (Sequelize) | Maps to (Mongoose) | Maps to (Zod) |
|---|---|---|---|
| string | DataTypes.STRING | String | z.string() |
| number | DataTypes.INTEGER | Number | z.number() |
| boolean | DataTypes.BOOLEAN | Boolean | z.boolean() |
| date | DataTypes.DATE | Date | z.coerce.date() |
Mark a field as optional by adding :optional as a third segment:
--fields name:string,description:string:optionalIf --fields is omitted, a default name:string field is used.
On PowerShell, always quote multi-field values (unquoted commas become spaces):
unc generate module events --fields "name:string,startsAt:date,description:string:optional"Configuration file
.uncjs.json is created during init and is required for all generate commands.
| Key | Description |
|---|---|
| language | "ts" or "js" |
| framework | Currently "express" (NestJS coming later) |
| orm | "mongoose", "prisma", or "sequelize" |
| eslint | Whether ESLint was included |
| prettier | Whether Prettier was included |
| husky | Whether Husky was included |
| version | CLI config schema version |
If you run generate outside an initialized project, the CLI will exit with an error asking you to run init first.
Path aliases
Generated projects use TypeScript path aliases for clean imports:
| Alias | Path |
|---|---|
| @types | src/types |
| @config | src/config |
| @loaders | src/loaders |
| @contracts | src/contracts |
| @combinedServices | src/combined-services |
| @services | src/services |
| @utils | src/utils |
| @routes | src/routes |
| @controllers | src/controllers |
| @constants | src/constants |
| @models | src/models |
| @schema | src/schemas |
| @middlewares | src/middlewares |
| @adapters | src/adapters |
| @interceptors | src/interceptors |
| @processes | src/processes |
Recommended workflow
init → generate module(s) → npm run dev- Initialize the project (runs
npm installfor you) - Generate modules for each entity/resource you need
- Customize generated files — add associations, business rules, auth middleware, etc.
- Develop with
npm run dev - Run with
npm run devornpm run build && npm start
Scripts in generated apps
| Script | Description |
|---|---|
| npm run dev | Start dev server with hot reload (nodemon + tsx) |
| npm run build | Compile TypeScript and resolve path aliases |
| npm start | Run compiled app from dist/ |
| npm run start:ts | Run TypeScript directly with tsx |
| npm run lint | Run ESLint |
| npm run lint:fix | Auto-fix lint issues |
| npm run format | Format code with Prettier |
Command reference
For a full breakdown of every command, flag, argument, and example, see COMMANDS.md.
Troubleshooting
Missing .uncjs.json
You are not inside an initialized project. Run unc init first, or cd into the generated app directory.
Base service not found
BaseService is generated during init. Re-run unc generate base-service only if you need to regenerate it.
Directory is not empty
init will prompt for confirmation if the target folder already has files. Use --force to skip the prompt:
unc init my-api --forceWrong ORM templates
The ORM is set at init time and stored in .uncjs.json. To switch ORMs, create a new project or manually replace the base service and models.
License
ISC
