Express Router vs App-Level Routing: When to Use Each
App-level routing is fine for tiny apps. Express Router is for growth. Here is when to use each.
Express Router vs App-Level Routing: When to Use Each
App-level routing (app.get, app.post) is fine for tiny apps. Express Router is for growth. Here is when to use each.
App-Level Routing
app.get('/users', listUsers);
app.post('/users', createUser);
app.get('/users/:id', getUser);
app.patch('/users/:id', updateUser);
app.delete('/users/:id', deleteUser);
app.get('/posts', listPosts);
app.post('/posts', createPost);
// ...
All routes in app.js. Works for tiny apps.
When App-Level Routing Is Fine
- Tiny apps with a handful of routes.
- Quick prototypes or scripts.
- Learning exercises.
When to Switch to Express Router
- More than ~10 routes.
- Multiple features (auth, users, posts, chat).
- Multiple developers working on the same codebase.
- You want to apply middlewares per feature.
How to Switch
- Create a router per feature in routes/.
- Move routes into the router.
- Mount the router in app.js.
// routes/users.js
const router = express.Router();
router.get('/', listUsers);
router.post('/', createUser);
router.get('/:id', getUser);
router.patch('/:id', updateUser);
router.delete('/:id', deleteUser);
module.exports = router;
// app.js
app.use('/users', require('./routes/users'));
app.use('/posts', require('./routes/posts'));
Benefits of Express Router
- Separation of concerns: each feature has its own file.
- Per-router middlewares: apply auth or validation to all routes in a feature.
- Cleaner app.js: only global middlewares, router mounts, and the error handler.
- Team scalability: different developers work on different routers without conflicts.
- Reusability: mount the same router under different paths (e.g., /api/v1/users and /api/v2/users).
The Takeaway
Use app-level routing for tiny apps and prototypes. Switch to Express Router when you have more than ~10 routes, multiple features, or multiple developers. Create a router per feature, mount it in app.js. Benefits: separation, per-router middlewares, clean app.js, team scalability, reusability.
When you have more than ~10 routes, multiple features (auth, users, posts), or multiple developers. App-level routing is fine for tiny apps and prototypes; switch to Router when the app grows.
Create a router per feature in routes/. Move routes into the router. Mount the router in app.js with app.use('/users', require('./routes/users')). Benefits: separation, per-router middlewares, cleaner app.js.
Separation of concerns (each feature has its own file), per-router middlewares (auth for a feature without repeating per route), cleaner app.js, team scalability (different devs work on different routers), and reusability (mount the same router under different paths).
Yes, but it gets messy. Pick one approach. If you have more than a few routes, use Router for all of them. Mixing makes the codebase inconsistent and harder to navigate.
Only: create the app, apply global middlewares (json, cors, helmet), mount routers with app.use, and register the error handler. Everything else lives in feature folders. A thin app.js is a sign of a well-organized app.
Ready to master Node.js completely?
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.
Master Node.js
Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course.

