Features
Docs
CLI
Benchmarks
Examples

© 2024 MoroJs

Project Structure

Learn how to organize your MoroJS projects for scalability and maintainability. From simple APIs to enterprise applications.

What You'll Learn

Simple single-file structure for small projects
Modular structure for larger applications
Enterprise architecture with functional modules
Configuration files and best practices
Progress1 of 4
1

Basic Project Structure

Start with a simple single-file structure. Perfect for small APIs and prototypes.

Simple API Structure (Based on Actual Examples)

typescript

1simple-api/
2├── src/
3│   └── server.ts          # Main application entry (single file)
4├── package.json
5├── package-lock.json
6├── tsconfig.json
7└── README.md
8
9# Example from actual simple-api implementation:
10# - Single server.ts file with all routes
11# - In-memory data storage
12# - Zod schemas defined inline
13# - Simple, focused structure
14
15# Content of src/server.ts:
16import { createApp, z } from '@morojs/moro';
17
18const app = createApp();
19
20const UserSchema = z.object({
21  name: z.string().min(2).max(50),
22  email: z.string().email(),
23  age: z.number().min(18).optional()
24});
25
26// Routes and logic in single file
27app.get('/', (req, res) => { /* ... */ });
28app.get('/users', (req, res) => { /* ... */ });
29app.post('/users').body(UserSchema).handler((req, res) => { /* ... */ });
30
31app.listen(3001);
2

Modular Structure (Recommended)

For larger applications, use functional modules for better organization and maintainability.

Real-time Chat Structure (Actual Example)

typescript

1real-time-chat/
2├── src/
3│   ├── server.ts          # Main server with WebSocket
4│   ├── services/          # Service layer
5│   │   ├── AuthService.ts
6│   │   └── ChatService.ts
7│   └── controllers/       # (empty in actual implementation)
8├── database/              # Database setup (if needed)
9├── test-client.html       # WebSocket test client
10├── package.json
11├── package-lock.json
12├── tsconfig.json
13└── README.md
14
15# Key features in actual implementation:
16# - WebSocket support with app.websocket()
17# - Simple authentication endpoints
18# - In-memory storage for demo
19# - Services for chat functionality
3

Enterprise Project Structure

For enterprise applications, use functional modules with clear separation of concerns.

Enterprise Project Structure (Actual Implementation)

typescript

1enterprise-app/
2├── src/
3│   ├── server.ts          # Main application bootstrap
4│   └── modules/           # Functional modules
5│       ├── users/
6│       │   ├── index.ts   # Module definition
7│       │   ├── routes.ts  # Route handlers
8│       │   ├── sockets.ts # WebSocket handlers
9│       │   ├── actions.ts # Business logic
10│       │   ├── schemas.ts # Zod schemas
11│       │   ├── types.ts   # TypeScript types
12│       │   └── config.ts  # Module config
13│       ├── orders/
14│       │   ├── index.ts
15│       │   ├── routes.ts
16│       │   ├── actions.ts
17│       │   └── types.ts
18│       ├── todos/
19│       │   ├── index.ts
20│       │   ├── routes.ts
21│       │   ├── actions.ts
22│       │   └── types.ts
23│       └── health/
24│           └── index.ts
25├── package.json
26├── package-lock.json
27├── tsconfig.json
28└── README.md
29
30# Key differences from complex documentation:
31# - Functional module architecture (no decorators)
32# - defineModule() instead of createModule()
33# - Pure actions.ts for business logic
34# - Simple routes.ts with function definitions
35# - No complex shared/config directories

Functional Module Example (Actual Implementation)

typescript

1// src/modules/users/index.ts - Functional Module Definition
2import { defineModule } from '@morojs/moro';
3import { routes } from './routes';
4import { sockets } from './sockets';
5import * as actions from './actions';
6import * as types from './types';
7
8export default defineModule({
9  name: 'users',
10  version: '1.0.0',
11  prefix: '/api/v1.0.0/users',
12  
13  // Register routes (functional approach)
14  routes,
15  
16  // Register WebSocket handlers
17  sockets,
18  
19  // Export module actions and types
20  actions,
21  types,
22  
23  // Module lifecycle hooks
24  onLoad: async (app) => {
25    console.log('👥 Users module loaded');
26  },
27  
28  onUnload: async (app) => {
29    console.log('👥 Users module unloaded');
30  }
31});
32
33// src/server.ts - Main application
34import { createApp } from '@morojs/moro';
35import UsersModule from './modules/users';
36import OrdersModule from './modules/orders';
37import HealthModule from './modules/health';
38
39async function createEnterpriseApp() {
40  const app = createApp({
41    cors: true,
42    compression: true,
43    helmet: true
44  });
45
46  // Register mock database
47  const mockDatabase = {
48    users: [
49      { id: 1, name: 'John Doe', email: 'john@example.com', role: 'admin' }
50    ]
51  };
52  app.database(mockDatabase);
53
54  // Load functional modules
55  await app.loadModule(HealthModule);
56  await app.loadModule(UsersModule);
57  await app.loadModule(OrdersModule);
58
59  return app;
60}
61
62const app = await createEnterpriseApp();
63app.listen(3002);
4

Configuration Files

Essential configuration files for your MoroJS project.

package.json

package.json (Based on Actual Examples)

typescript

1{
2  "name": "simple-api-example",
3  "version": "1.0.0",
4  "private": true,
5  "description": "Simple API demonstration showing basic Moro framework usage",
6  "main": "src/server.ts",
7  "scripts": {
8    "dev": "NODE_ENV=development ts-node src/server.ts",
9    "dev:watch": "NODE_ENV=development ts-node-dev --respawn --transpile-only src/server.ts",
10    "build": "tsc",
11    "start": "NODE_ENV=production node dist/server.js",
12    "test": "echo "No tests specified"",
13    "switch:local": "rm -rf node_modules package-lock.json && npm install file:../../MoroJS",
14    "switch:npm": "rm -rf node_modules package-lock.json && npm install @morojs/moro@latest"
15  },
16  "dependencies": {
17    "@morojs/moro": "file:../../MoroJS"
18  },
19  "devDependencies": {
20    "@types/node": "^20.10.0",
21    "ts-node": "^10.9.1",
22    "ts-node-dev": "^2.0.0",
23    "typescript": "^5.3.2"
24  },
25  "keywords": [
26    "moro",
27    "api",
28    "simple",
29    "example"
30  ]
31}

tsconfig.json

tsconfig.json (ESM Configuration)

typescript

1{
2  "compilerOptions": {
3    "target": "ES2022",
4    "lib": ["ES2022"],
5    "module": "NodeNext",
6    "moduleResolution": "NodeNext",
7    "esModuleInterop": true,
8    "allowSyntheticDefaultImports": true,
9    "strict": true,
10    "skipLibCheck": true,
11    "forceConsistentCasingInFileNames": true,
12    "outDir": "./dist",
13    "rootDir": "./src",
14    "declaration": true,
15    "declarationMap": true,
16    "sourceMap": true,
17    "experimentalDecorators": true,
18    "emitDecoratorMetadata": true,
19    "resolveJsonModule": true
20  },
21  "include": [
22    "src/**/*"
23  ],
24  "exclude": [
25    "node_modules",
26    "dist"
27  ]
28}

Organization Best Practices

File Organization

  • Group related functionality in modules
  • Keep schemas close to their usage
  • Separate business logic from routes
  • Use consistent naming conventions

Code Organization

  • Export modules from index files
  • Use TypeScript path mapping
  • Keep configuration centralized
  • Document your structure

Next Steps