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 helper

Key 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.