Project Structure
Organize a growing app into routes, controllers, models and middleware folders.
Small apps fit in one file, but real projects benefit from a clear layout. A common MVC-style structure separates concerns so each file has one job.
Example
// app.js
const express = require('express');
const app = express();
app.use(express.json());
app.use('/users', require('./routes/users'));
app.use('/posts', require('./routes/posts'));
app.use((err, req, res, next) => {
res.status(err.status || 500).json({ error: err.message });
});
module.exports = app;When to use it
- A growing Express API is reorganised into routes/, controllers/, services/, and middleware/ folders so each layer has a clear responsibility.
- A team enforces that app.js only contains the Express setup and app.listen() lives in server.js so tests can import the app without starting the server.
- A developer adds an index.js barrel file to each feature folder so import paths stay short even as the project grows.
More examples
Recommended folder layout
Shows a scalable project layout that separates routing, business logic, and HTTP concerns into dedicated directories.
my-api/
src/
routes/ # express.Router() files
controllers/ # request handlers
services/ # business logic + DB calls
middleware/ # custom middleware
models/ # Mongoose/Sequelize models
app.js # Express setup, middleware registration
server.js # app.listen() entry pointapp.js vs server.js split
Keeps app.js free of listen() so test suites can import the configured app and call supertest without binding a port.
// app.js — export app WITHOUT calling listen
const express = require('express');
const app = express();
app.use(express.json());
app.use('/users', require('./routes/users'));
module.exports = app;
// server.js — call listen here only
const app = require('./app');
app.listen(process.env.PORT || 3000);Route barrel index file
A barrel router in routes/index.js mounts all feature routers, so app.js only needs one app.use() call to register the entire API.
// routes/index.js
const express = require('express');
const router = express.Router();
router.use('/users', require('./users'));
router.use('/products', require('./products'));
router.use('/orders', require('./orders'));
module.exports = router;
// app.js
app.use('/api/v1', require('./routes'));
Discussion