express.Router() is the tool Express gives you for organizing routes into separate, mountable modules instead of one giant app.js file. This lesson shows how to structure a growing application around routers.
What Is express.Router()?
express.Router() creates a new, isolated router object that behaves like a mini Express application: it has its own .get(), .post(), .use(), and its own middleware stack, but no .listen(), it must be mounted onto a real app (or another router) to actually receive requests.
This lets you split a large application into focused files, one router per resource, users, orders, products, and wire them together in one place.
express.Router() accepts an options object, e.g. { mergeParams: true } for nested routers.
A router supports every method Express supports on app.
Mounting the same router at multiple paths is possible but uncommon.
Routers can be nested inside other routers for deeply organized route trees.
Express Router Cheatsheet
Common router operations you will use while structuring a real app.
Task
Example
Create router
const router = express.Router();
Define route
router.get('/:id', getUser);
Router middleware
router.use(requireAuth);
Mount router
app.use('/users', usersRouter);
Nested router
express.Router({ mergeParams: true })
Export router
module.exports = router;
Why Routers Matter as Apps Grow
A single app.js file with fifty route definitions quickly becomes unreadable and hard to test. Splitting routes by resource into their own router files keeps each file focused, easy to review, and easy to reuse or move without touching unrelated code.
One router per resource (users.router.js, orders.router.js, ...).
Each router file can be tested in isolation with supertest.
app.js becomes a short, readable list of mounted routers.
Teams can work on different routers in parallel with fewer merge conflicts.
Typical Project Wiring
A common pattern collects all routers under a single /api prefix, and further versions or groups them from there.
Defining routes directly on app for every resource instead of splitting them into routers.
Forgetting to mount a router with app.use(), its routes will simply never be reachable.
Duplicating the mount path inside the router's own route definitions (e.g. /users/:id inside a router already mounted at /users).
Not exporting the router with module.exports, leaving other files unable to import it.
Key Takeaways
express.Router() creates a modular, mountable set of routes and middleware.
Paths defined inside a router are relative to its mount path.
Splitting routes by resource keeps a growing app organized and testable.
Routers can have their own middleware, independent of the main app.
Pro Tip
As soon as a file has more than two or three routes, extract it into its own router file, waiting until app.js is already a mess makes the refactor far more painful.
You now know how to organize routes with express.Router(). Next, learn how to nest routers for parent-child resources in the Nested Routes lesson.