@mcansh/react-router-fastify weekly downloads statistics
By mcansh · npm · Vite plugins
Fastify adapter and Vite development plugin for React Router v8 framework mode
@mcansh/react-router-fastify has 7,194 recorded weekly downloads on npm, ranking #1071 of 2,644 tracked listings.
About @mcansh/react-router-fastify
react-router-fastify
A Fastify adapter for React Router v8 framework mode, plus a Vite plugin so react-router dev runs through your Fastify server.
Features
- Adapts Fastify requests and replies to React Router's Web Fetch request/response runtime
- Registers React Router as a Fastify catch-all route while preserving your own Fastify routes
- Loads
virtual:react-router/server-buildduring development - Serves
build/clientwith@fastify/staticin production - Provides a Vite plugin that mounts your Fastify app during
react-router dev - Preserves shared server/app module identity for React Router context tokens
Installation
npm i @mcansh/react-router-fastify fastify react-router @react-router/node
npm i -D @react-router/dev vite
React Router v8 currently requires Node >=22.22.0.
Usage
Create a server module that exports a factory. The factory receives the Vite dev server in development and undefined in production.
// server.ts
import { pathToFileURL } from "node:url"
import { fastifyReactRouter } from "@mcansh/react-router-fastify"
import { fastify } from "fastify"
import type { ViteDevServer } from "vite"
export async function createServer(vite?: ViteDevServer) {
let app = fastify()
app.get("/api/health", async () => ({ ok: true }))
await app.register(fastifyReactRouter, { devServer: vite })
return app
}
let isMain = import.meta.url === pathToFileURL(process.argv[1]).href
if (isMain) {
let app = await createServer()
await app.listen({ port: 3000, host: "0.0.0.0" })
}
Add the Vite plugin so react-router dev uses that Fastify server:
// vite.config.ts
import { reactRouter } from "@react-router/dev/vite"
import { fastifyReactRouterDev } from "@mcansh/react-router-fastify/vite"
import { defineConfig } from "vite"
export default defineConfig({
plugins: [reactRouter(), fastifyReactRouterDev({ entry: "./server.ts" })],
})
Use the normal React Router commands:
{
"scripts": {
"dev": "react-router dev",
"build": "react-router build",
"start": "NODE_ENV=production node ./server.js"
}
}
Example
A runnable example lives in examples/basic:
pnpm install
pnpm run example:dev
The example includes a Fastify API route at /api/health, getLoadContext
that seeds React Router context, root route middleware that updates that same
context, and a vite.config.ts that uses fastifyReactRouterDev with the
standard react-router dev command.
Shared Context
React Router v8 uses RouterContextProvider for loaders, actions, and
middleware. When your Fastify server and React Router app both need the same
context token, put that token in a module that both sides import through the
same package import specifier.
Add a package import for the shared module:
{
"imports": {
"#request-info": "./app/request-info.ts"
}
}
Create the context token in your app:
// app/request-info.ts
import { createContext } from "react-router"
export interface RequestInfo {
requestId: string
userAgent: string
}
export let requestInfoContext = createContext<RequestInfo>()
Seed it from getLoadContext:
// server.ts
import { requestInfoContext } from "#request-info"
import { fastifyReactRouter } from "@mcansh/react-router-fastify"
import { RouterContextProvider } from "react-router"
app.register(fastifyReactRouter, {
devServer: vite,
getLoadContext(request) {
let context = new RouterContextProvider()
context.set(requestInfoContext, {
requestId: request.id,
userAgent: request.headers["user-agent"] ?? "unknown",
})
return context
},
})
Read or update the same context from React Router middleware and route modules:
// app/root.tsx
import { requestInfoContext } from "#request-info"
import type { MiddlewareFunction } from "react-router"
export const middleware: MiddlewareFunction[] = [
async ({ context }, next) => {
let requestInfo = context.get(requestInfoContext)
context.set(requestInfoContext, requestInfo)
return next()
},
]
// app/routes/home.tsx
import { requestInfoContext } from "#request-info"
import type { LoaderFunctionArgs } from "react-router"
export async function loader({ context }: LoaderFunctionArgs) {
return {
requestInfo: context.get(requestInfoContext),
}
}
Tell the Vite plugin to keep that package import external in React Router's SSR build:
// vite.config.ts
import { reactRouter } from "@react-router/dev/vite"
import { fastifyReactRouterDev } from "@mcansh/react-router-fastify/vite"
import { defineConfig } from "vite"
export default defineConfig({
plugins: [
reactRouter(),
fastifyReactRouterDev({
entry: "./server.ts",
externalizeServerEntryImports: ["#request-info"],
}),
],
})
This prevents the production server bundle from inlining a second
createContext() instance. The built React Router server keeps
import { requestInfoContext } from "#request-info", so server.ts,
middleware, and loaders all use the same token.
Production
Without a Vite dev server, fastifyReactRouter imports build/server/index.js and serves static files from build/client:
react-router build
NODE_ENV=production node ./server.js
If your build output uses different paths, pass them directly:
await app.register(fastifyReactRouter, {
serverBuildPath: "dist/server.js",
clientBuildDirectory: "dist/client",
})
API
fastifyReactRouter options:…
Description from the npm listing.
- adapter
- fastify
- react-router
- vite
- vite-plugin
README badge
Show your rank in a README or on your website. The badge updates automatically.
Charts
Images: 30d · 1y · all time · 1600×900 dark
Adoption over time
7/30/90-day growth
Ranking history
Listing placement
Listing placement
Filled points are observed values; hollow points come from Internet Archive snapshots of the listing page. Dashed segments span periods with no observations — values between points are not interpolated.
Each band is one page of 20. Weekly downloads on a linear scale. Placement is projected from weekly downloads, so it can differ from the marketplace's own sort order. Hover a dot to see the listing.
Recent observations
Full history (1)Similar npm Vite plugins plugins
All 20 @mcansh/react-router-fastify alternativesData source
Weekly downloads (trailing 7 complete days) come from the official npm downloads API. Downloads include CI and mirrors and are not equivalent to installs or users. npm publishes no ratings.
Listing: https://www.npmjs.com/package/@mcansh/react-router-fastify. First seen Oct 28, 2026; last successful collection Oct 28, 2026. See the methodology.