exrout
v1.1.2
Published
Automatically load and register Express routes from folder structure
Maintainers
Readme
EXROUT 🚀
Express Auto Route Loader — Automatically load and register Express routes based on your folder structure. Stop manually importing every route file!
✨ Features
- 📂 Auto-load routes from folders & subfolders
- 📄 Smart index files —
index.js/tsmaps to folder root - 🔁 Dual module support — Works with CommonJS and ES Modules
- 🧠 File-based params —
[id].tsbecomes:id - ⚡ Async router support — Dynamic route initialization
- 🧩 Global middleware — Apply middleware to all routes
- 🧭 Route prefixing — Add
/apior any prefix - 🔥 Hot reload — Auto-refresh routes in development
- 🚫 Exclusion patterns — Skip test files, helpers, etc.
- 📊 Route logging — See loaded routes in console
- 🔒 TypeScript first — Full type safety and exports
📦 Installation
npm install exroutFor hot reload support (optional):
npm install chokidar🚀 Quick Start
ES Modules
import express from "express";
import autoRoutes from "exrout";
const app = express();
await autoRoutes(app, "./routes", {
prefix: "/api",
log: true
});
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});CommonJS
const express = require("express");
const autoRoutes = require("exrout");
const app = express();
autoRoutes(app, "./routes").then(() => {
app.listen(3000);
});📁 Folder Structure → Routes
Your file structure automatically becomes your API routes:
routes/
├── index.ts → /
├── users.ts → /users
├── posts.ts → /posts
├── auth/
│ ├── index.ts → /auth
│ ├── login.ts → /auth/login
│ ├── register.ts → /auth/register
│ └── [token].ts → /auth/:token
└── users/
├── index.ts → /users
└── [id].ts → /users/:id🧩 Writing Routes
Each route file exports an Express Router:
import { Router } from "express";
const router = Router();
router.get("/", (req, res) => {
res.json({ message: "Hello from users!" });
});
router.post("/", (req, res) => {
res.json({ message: "User created!" });
});
export default router;⚙️ Configuration Options
await autoRoutes(app, "./routes", {
prefix: "/api", // Prefix all routes
middleware: [authMiddleware, loggerMiddleware], // Global middleware
log: true, // Log loaded routes
watch: true, // Hot reload in development
exclude: ["*.test.ts", "_*", "helpers/*"] // Exclusion patterns
});Options Reference
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| prefix | string | "" | Prefix for all routes (e.g., /api) |
| middleware | RequestHandler[] | [] | Global middleware applied to all routes |
| log | boolean | false | Log loaded routes to console |
| watch | boolean | false | Enable hot reload (requires chokidar) |
| exclude | string[] | [] | Glob patterns to exclude files |
Default Exclusions
These patterns are excluded by default:
*.test.ts/*.test.js*.spec.ts/*.spec.js_*(files starting with underscore)*.d.ts(TypeScript declaration files)
🧠 Dynamic Route Parameters
Use bracket notation for dynamic segments:
routes/
└── users/
└── [id].ts → /users/:id// routes/users/[id].ts
import { Router } from "express";
const router = Router();
router.get("/", (req, res) => {
res.json({ userId: req.params.id });
});
export default router;Multiple params work too:
routes/
└── [category]/
└── [productId].ts → /:category/:productId⚡ Async Router Factory
For routes that need async initialization:
import { Router } from "express";
import { connectDatabase } from "./db";
export default async function createRouter() {
await connectDatabase();
const router = Router();
router.get("/", async (req, res) => {
const data = await fetchData();
res.json(data);
});
return router;
}🔥 Hot Reload (Development)
Enable automatic route reloading when files change:
await autoRoutes(app, "./routes", {
watch: process.env.NODE_ENV === "development"
});⚠️ Requires
chokidarto be installed.
🔌 TypeScript Support
Full TypeScript support with exported types:
import autoRoutes, {
AutoRoutesOptions,
AutoRoutesResult,
RouteInfo,
} from "exrout";
const options: AutoRoutesOptions = {
prefix: "/api",
log: true,
};
const result: AutoRoutesResult = await autoRoutes(app, "./routes", options);
result.routes.forEach((route: RouteInfo) => {
console.log(`Route: ${route.path} -> ${route.file}`);
});📊 Return Value
autoRoutes returns a promise with information about loaded routes:
const result = await autoRoutes(app, "./routes");
console.log(result.routes);
// [
// { path: "/", file: "/abs/path/routes/index.ts" },
// { path: "/users", file: "/abs/path/routes/users.ts" },
// { path: "/users/:id", file: "/abs/path/routes/users/[id].ts" }
// ]
// If watch mode is enabled, you can stop watching:
result.close?.();🚫 Excluding Files
Skip certain files from being loaded as routes:
await autoRoutes(app, "./routes", {
exclude: [
"*.test.ts", // Skip test files
"_*", // Skip files starting with _
"helpers/*", // Skip helper directories
"*.backup.*" // Skip backup files
]
});📝 Examples
API with Authentication
import express from "express";
import autoRoutes from "exrout";
import { authMiddleware } from "./middleware/auth";
const app = express();
app.use(express.json());
// Public routes
await autoRoutes(app, "./routes/public");
// Protected routes with auth middleware
await autoRoutes(app, "./routes/protected", {
prefix: "/api",
middleware: [authMiddleware]
});
app.listen(3000);Microservice with Versioning
import express from "express";
import autoRoutes from "exrout";
const app = express();
// Version 1 API
await autoRoutes(app, "./routes/v1", { prefix: "/api/v1" });
// Version 2 API
await autoRoutes(app, "./routes/v2", { prefix: "/api/v2" });
app.listen(3000);🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT © Marouane Akrich
