Master Guides
Project Structure
One repo, two services, a clear place for everything.
master new generates a decoupled monorepo managed with npm workspaces: a MasterController API in backend/ and a Next.js app in frontend/.
The tree#
my-app/
my-app/
├── package.json # workspaces + dev/build/start scripts
├── master.config.js # ports + frontend toggle
├── .env.example # NEXT_PUBLIC_API_URL, FRONTEND_URL
├── backend/
│ ├── package.json # mastercontroller, masterrecord, socket.io
│ ├── server.js # boots the framework
│ ├── app/
│ │ ├── routes.js # URL → controller#action
│ │ ├── controllers/ # API controllers (this.returnJson)
│ │ │ └── healthController.js
│ │ ├── models/
│ │ │ ├── AppContext.js # registers entities (dbset)
│ │ │ ├── db.js # shared context instance
│ │ │ ├── User.js # an example entity
│ │ │ └── db/migrations/
│ │ └── sockets/
│ ├── middleware/ # auto-loaded pipeline (01-logger.js)
│ └── config/environments/ # env.development.json, env.production.json
└── frontend/
├── package.json # next, react
├── next.config.mjs
└── app/ # Next.js App Router
├── layout.tsx
├── page.tsx # calls the backend /health
└── lib/api.ts # typed fetch helperKey files#
master.config.js#
Controls the dev/build/start orchestration — ports and whether a frontend exists.
master.config.js
export default {
frontend: true,
backendPort: 3001,
frontendPort: 3000,
backendDir: 'backend',
frontendDir: 'frontend',
};backend/app/models/db.js#
A shared, ready-to-use database handle you import in controllers:
javascript
import AppContext from './AppContext.js';
const db = new AppContext();
export default db;frontend/app/lib/api.ts#
A typed fetch helper that talks to the backend via NEXT_PUBLIC_API_URL.
Backend-only apps
Scaffold with
--skip-frontend and you get just backend/ plus a master.config.js with frontend: false.