One entry point, every middleware
Next.js gives you one middleware file. NEMO lets you keep writing small, named middleware functions and dispatches them by path, so the entry point stays a routing table instead of growing into a switch statement.
import { createNEMO } from "@zanreal/nemo";
export const middleware = createNEMO({
"/dashboard/:path*": [requireSession],
"/api/:path*": [rateLimit, requireApiKey],
});Maintained by ZanReal as part of its OSS Program
NEMO is a company project rather than one person's side project: the package, the repository and the release process belong to ZanReal, and the licence stays MIT. What that means.
First, let the code get the word out
The same routing logic, written by hand and written with NEMO.
import { NextResponse, type NextRequest } from "next/server";
export const middleware = async (req: NextRequest) => {
let user = undefined;
let team = undefined;
const token = req.headers.get("token");
if (req.nextUrl.pathname.startsWith("/auth")) {
user = await getUserByToken(token);
if (!user) {
return NextResponse.redirect("/login");
}
return NextResponse.next();
}
if (req.nextUrl.pathname.startsWith("/team/") || req.nextUrl.pathname.startsWith("/t/")) {
user = await getUserByToken(token);
if (!user) {
return NextResponse.redirect("/login");
}
team = await getTeamBySlug(req.nextUrl.searchParams.get("slug"));
if (!team) {
return NextResponse.redirect("/");
}
return NextResponse.next();
}
return NextResponse.next();
};import { createNEMO } from "@zanreal/nemo";
import { auth } from "@/app/(auth)/auth/_middleware";
import { team } from "@/app/(team)/team/_middleware";
const globalMiddlewares = {
before: auth, // OR: [auth, ...]
};
const middlewares = {
"/auth/:path*": auth,
"/(team|t)/:slug/:path*": team, // OR: [team, ...]
};
export const middleware = createNEMO(middlewares, globalMiddlewares);Every branch that used to be a path check is a key. The functions themselves live next to the routes they guard, and the entry point stops growing.
Simplify your middlewares now
Supports
Dynamic segments
Run your middleware for any route or dynamic segment.
Functions chaining
Chain multiple middlewares for a single group.
Shared context
Functions can share context between each other.
Open source
Open-source
Something is missing? Just add it, or post an issue on GitHub.
Developer experience
Typed end to end, no build step of its own, and an API small enough to hold in your head.
Want to help with this project?
Review existing issues, make PRs with what is missing.
Other versions
Each major keeps its own documentation. v1 and v2 stay published for anyone who has not upgraded yet.
Was this helpful?
M↓supported.