
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
react-router-dataflow
Advanced tools
A tiny, fully type-safe composer for React Router loaders, actions, and route guards
A tiny, fully type-safe composer for React Router loaders, actions, and route guards.
React Router loaders and actions scale poorly once you start sharing logic. Context becomes implicit, middleware composition is manual, and type safety quickly degrades.
React Router Dataflow fixes this by letting you compose loaders, actions, and route guards as typed pipelines, producing a fully type-safe execution context per route.
import { Loader } from "react-router-dataflow";
const loader = Loader
.with(parseParams)
.with(fetchData)
.build(async (_, { params, data }) => {
// params and data are guaranteed to be available here
return data;
});
// => loader can be used as a standard React Router loader
React Router Dataflow is useful as soon as your routes have different contexts or you start sharing logic between loaders or actions. It makes execution order explicit, context predictable, and removes the need for defensive runtime checks.
npm install react-router-dataflow
yarn add react-router-dataflow
pnpm add react-router-dataflow
Compose loaders and actions as pipelines with a progressively typed context.
import { LoaderMiddleware, Loader } from "react-router-dataflow";
// Explicitly typed middleware (optional, but recommended)
const mw: LoaderMiddleware<{ data: string }> = async (args) => {
/* do stuff with args */
return { data: "OK" };
};
Loader.with(mw);
Middlewares steps (for loader/action context pipelines) can also be typed action-only (
ActionMiddleware) or universal (Middleware).
import { Loader } from "react-router-dataflow";
Loader
.with(async (args) => {
/* do stuff with args */
return { data: "OK" };
})
.with(async (_, { data }) => {
// data is guaranteed here
return null; // no context enrichment
});
import { Loader } from "react-router-dataflow";
// When loader should send data
Loader
.with(mw)
.with(async () => ({ additional: 1 }))
.build(async (_, { data, additional }) => {
// data and additional are guaranteed here
return { data, additional };
});
// When it should not
Loader.with(mw).build();
import { Action } from "react-router-dataflow";
// throws 405 response for any method not handled (ignoring case)
Action.build({
POST: async (args) => ({ data: "post" }),
DELETE: async (args) => ({ deleted: true })
});
// Runs middlewares then throws 405 response for any method not handled (ignoring case)
Action
.with(mw)
.with(async () => ({ additional: 1 }))
.build({
POST: async (_, { data, additional }) => {
/* data and additional are guaranteed here */
return { data, additional };
},
DELETE: async (_, { data, additional }) => {
/* data and additional are guaranteed here */
return { deleted: true };
}
});
For more advanced patterns such as context enforcement, parameterized middlewares and middleware factorization, see the advanced middleware documentation.
React Router Dataflow includes support for building React Router middlewares with a fully typed internal pipeline, using the same with/build builder API as loaders and actions.
RouteMiddleware is a builder that produces a single React Router middleware suitable for guarding routes and short-circuiting navigation.
RouteMiddlewareis not related to middlewares types used byLoaderandActionbuilders which are composing functions of loaders and actions.
RouteMiddleware focuses on composing route guards by letting you compose a sequence of typed steps called route requirements.
Each requirement runs before the route is entered, can enrich internal context, and can throw a Response to block navigation.
Route requirements can be predefined in the same way as loaders and actions middlewares using RouteRequirement type.
RouteMiddlewaredoes not support post-processing or response interception. If you need a pre/post middleware, write a React Router middleware directly and compose it alongsideRouteMiddleware.
Terminology
- Middleware: a loader/action pipeline step
- RouteMiddleware: a builder that produces a React Router middleware
- RouteRequirement: a typed guard step executed inside a RouteMiddleware
import { RouteMiddleware } from "react-router-dataflow";
import { requireAuth } from "~/guards/require-auth";
// Ensures user is authenticated and has "admin" role
RouteMiddleware
.with(requireAuth) // => { user }
.build(async (_, { user }) => {
if (user.role !== "admin") {
throw new Response("Unauthorized", { status: 401 });
}
return null;
});
Loaders, actions, and route middlewares created with React Router Dataflow are standard React Router primitives and behave the same way on the client and on the server. They can be used in:
createBrowserRouter)<Route loader/>)// app/routes/data.$id.tsx
import { Loader, Action } from "react-router-dataflow";
import { requireAuth } from "~/guards/require-auth";
import { dataFromParams } from "~/middlewares/data-from-params";
// Auth is enforced on the route
export const middleware = [
RouteMiddleware
.with(requireAuth)
.build()
];
// => reached only if authenticated, get data from route params
export const loader = Loader
.with(dataFromParams) // => { data }
.build(async (_, { data }) => data);
// => reached only if authenticated, only PATCH/patch requests are handled
export const action = Action
.with(dataFromParams) // => { data }
.build({
PATCH: async ({ request }, { data }) => {
const updatedData = /* data update using request */;
return updatedData;
}
});
const ExamplePage = () => <h1>Example page</h1>;
export default ExamplePage;
FAQs
A tiny, fully type-safe composer for React Router loaders, actions, and route guards
We found that react-router-dataflow demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.