@mcansh/react-router-fastify 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,435 @@
1
+ # @mcansh/react-router-fastify
2
+
3
+ ## 5.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - c51dd78: Replace the old server integration with a Web Fetch request/response adapter for React Router.
8
+
9
+ Fastify requests are now converted into Fetch `Request` objects with absolute URLs based on the original incoming URL, normalized headers, streamed request bodies for non-GET/HEAD requests, serialized parsed JSON bodies, and abort signals tied to the Fastify reply lifecycle.
10
+
11
+ React Router `Response` objects are now written back through Fastify with status, headers, streamed response bodies, bodyless responses, and multiple `Set-Cookie` headers preserved when the runtime exposes `Headers.getSetCookie()`.
12
+
13
+ `createRequestHandler` now accepts either a React Router server build or a build loader function, passes the configured mode through to React Router, and resolves `getLoadContext(request, reply)` for each request before handing control to React Router.
14
+
15
+ - c51dd78: Refresh the docs, example app, tests, and build tooling around the React Router rewrite.
16
+
17
+ The package README now documents the Fastify server factory pattern, `react-router dev`, production build/start commands, `fastifyReactRouter` options, the lower-level handler API, and React Router 8 `RouterContextProvider` usage.
18
+
19
+ The examples have been consolidated to a single `examples/basic` app that demonstrates React Router framework mode, a custom Fastify server, a Fastify API route beside the React Router catch-all, `fastifyReactRouterDev`, and shared context tokens through a `#request-info` package import. The old Remix template version of the basic app, the separate Vite Remix example, the playground, and the standalone React Router example were removed or replaced.
20
+
21
+ The package test suite was rewritten around the new adapter surface, covering request/header/body conversion, response streaming and cookies, load context propagation, static-file cache headers, Vite SSR module loading, and dev-plugin import externalization.
22
+
23
+ The workspace now builds with `tsdown` as an ESM-only package with generated declarations, `publint`, and the ESM `attw` profile. Project tooling moved from ESLint and Prettier to `oxlint` and `oxfmt`, the changeset helper scripts were migrated to TypeScript files, CI/package-preview checks were simplified, and old Remix workspace overrides and deployment targets were removed.
24
+
25
+ - c51dd78: Rebuild the package as a React Router 8 framework-mode Fastify adapter.
26
+
27
+ This is a breaking rewrite of the public API and package shape. The Remix-focused adapter APIs have been removed:
28
+
29
+ - Removed `remixFastify` and Remix request-handler support.
30
+ - Removed the `@mcansh/react-router-fastify/middleware` and `@mcansh/react-router-fastify/react-router` subpath exports.
31
+ - Removed the generated CommonJS proxy files for those subpaths.
32
+ - Removed CommonJS package output. The package is now ESM-only and publishes `./dist/index.mjs` plus `./dist/vite.mjs`.
33
+ - React Router 8, `@react-router/node` 8, Fastify 5, and Node `>=22.22.0` are now required.
34
+
35
+ The main export now provides `fastifyReactRouter`, `createRequestHandler`, lower-level request/response adapter helpers (`createHeaders`, `createRequest`, `createUrl`, and `sendResponse`), and the related public types.
36
+
37
+ `fastifyReactRouter` registers React Router as a Fastify catch-all route while preserving Fastify routes that were registered first. In development it loads `virtual:react-router/server-build` from Vite; in production it imports `build/server/index.js` by default and serves `build/client` with `@fastify/static`.
38
+
39
+ The production static-file handler now supports separate cache controls for immutable build assets and other client files through `assetCacheControl` and `fileCacheControl`. The catch-all route can also receive Fastify `routeOptions`.
40
+
41
+ - c51dd78: Add the `@mcansh/react-router-fastify/vite` entry point with `fastifyReactRouterDev`.
42
+
43
+ The Vite plugin lets `react-router dev` run through the app's own Fastify server instead of a separate manual server process. It loads a configurable server entry, calls the configured factory export, waits for `app.ready()`, and mounts Fastify after Vite's own middleware so Vite internals and HMR continue to run first.
44
+
45
+ The plugin also closes and reloads the Fastify app when watched files change or unlink, and when the Vite HTTP server closes. SSR module loading uses Vite's environment runner when available and falls back to `ssrLoadModule` for older Vite server shapes.
46
+
47
+ For production builds, `fastifyReactRouterDev` can keep local and `#` imports from the server entry external in the React Router SSR build. This preserves singleton module identity for shared values such as React Router context tokens used by `getLoadContext`, middleware, and route loaders.
48
+
49
+ ### Patch Changes
50
+
51
+ - fad8fbc: feat: support vite 8
52
+ - c51dd78: Use Vite's virtual React Router server build whenever a dev server is present, so production `build` overrides no longer disable hot-reloaded development builds.
53
+
54
+ ## 4.1.2
55
+
56
+ ### Patch Changes
57
+
58
+ - await promise in the plugin. hopefully resolves https://github.com/mcansh/remix-fastify/issues/543 ([`904223434c3020a46b1516122922631bf8bb5de9`](https://github.com/mcansh/remix-fastify/commit/904223434c3020a46b1516122922631bf8bb5de9))
59
+
60
+ ## 4.1.1
61
+
62
+ ### Patch Changes
63
+
64
+ - allow passing options to childServer for use cases of other logging set ups ([#541](https://github.com/mcansh/remix-fastify/pull/541))
65
+
66
+ ```
67
+ fastify.register(reactRouterFastify, {
68
+ childServerOptions: { logLevel: 'silent' }
69
+ })
70
+ ```
71
+
72
+ - dont `export type *` for subpath reexports ([#540](https://github.com/mcansh/remix-fastify/pull/540))
73
+
74
+ ## 4.1.0
75
+
76
+ ### Minor Changes
77
+
78
+ - replace tsup with tsdown ([#529](https://github.com/mcansh/remix-fastify/pull/529))
79
+ - remove index re-export, point main to ./remix ([#534](https://github.com/mcansh/remix-fastify/pull/534))
80
+
81
+ before this PR, both `.` (bare import) and `./remix` (sub path import) would both be generated, now only the bare import is available.
82
+
83
+ ### Patch Changes
84
+
85
+ - fix: dont clone response when streaming body ([#525](https://github.com/mcansh/remix-fastify/pull/525))
86
+
87
+ ## 4.0.8
88
+
89
+ ### Patch Changes
90
+
91
+ - f4580d8: add support for react-router middleware
92
+
93
+ ## 4.0.7
94
+
95
+ ### Patch Changes
96
+
97
+ - 373f34f: rethrow caught error when destroying stream
98
+
99
+ ## 4.0.6
100
+
101
+ ### Patch Changes
102
+
103
+ - 629269a: destroy stream on errors
104
+
105
+ ## 4.0.5
106
+
107
+ ### Patch Changes
108
+
109
+ - 74abcef: eagerly build output
110
+
111
+ ## 4.0.4
112
+
113
+ ### Patch Changes
114
+
115
+ - 0601d19: expand vite peer dependency range to allow vite@6
116
+
117
+ ## 4.0.3
118
+
119
+ ### Patch Changes
120
+
121
+ - a8559e0: fix: mark getLoadContext as optional
122
+
123
+ ## 4.0.2
124
+
125
+ ### Patch Changes
126
+
127
+ - bf0b464: fix: update url generation for fastify v5
128
+ - cd7e8d5: chore: update adapter logic for aborting requests
129
+ - 206509a: feat: add react router entry point
130
+
131
+ ## 4.0.1
132
+
133
+ ### Patch Changes
134
+
135
+ - 54fff80: Make cache-control headers work again.
136
+
137
+ ## 4.0.0
138
+
139
+ ### Major Changes
140
+
141
+ - 3df5d21: feat: fastify v5 support
142
+
143
+ ## 3.4.1
144
+
145
+ ### Patch Changes
146
+
147
+ - 88e2ad1: fix asset serving when using a basename
148
+
149
+ ## 3.4.0
150
+
151
+ ### Minor Changes
152
+
153
+ - 6d074ed: return streams directly from remix to fastify
154
+
155
+ ### Patch Changes
156
+
157
+ - 352c74f: New optional parameter to customize the `@fastify/static` plugin options. This can be useful to customize options like `decorateReply` or `setHeaders` to match your needs or when you already have a `@fastify/static` plugin registered.
158
+ - bd2a09c: New optional parameter to provide a custom server build for production. If not provided, it will be loaded using `import()` with the server build path provided in the options.
159
+
160
+ ## 3.3.3
161
+
162
+ ### Patch Changes
163
+
164
+ - be05e8b: The Remix Vite plugin allows you to customize the filename. This change allows you to pass a custom server file name to the Fastify plugin
165
+
166
+ ```js vite.config.ts
167
+ export default defineConfig({
168
+ plugins: [remix({ serverFilename: "example.js" })],
169
+ });
170
+ ```
171
+
172
+ ```js server.js
173
+ await app.register(remixFastify, {
174
+ serverFilename: "example.js",
175
+ });
176
+ ```
177
+
178
+ ## 3.3.2
179
+
180
+ ### Patch Changes
181
+
182
+ - b83f33c: allows you to customize Vite dev server options. useful for reusing the fastify http(s) server for hmr in development
183
+ - 822b878: use file urls for esm for windows compatibility
184
+
185
+ ## 3.3.1
186
+
187
+ ### Patch Changes
188
+
189
+ - a7fcb6d: allows you to customize the cache control for both the files in the build directory as well as your public directory if you need to. using `pretty-cache-header` under the hood so things like `1y` or `30 days` will work
190
+
191
+ ```js
192
+ await app.register(remixFastify, {
193
+ assetCacheControl: {},
194
+ defaultCacheControl: {},
195
+ });
196
+ ```
197
+
198
+ - a7fcb6d: fix cache control so that build assets are immutable and cached for 1 year instead of everything being cached for 1 hour
199
+
200
+ ## 3.3.0
201
+
202
+ ### Minor Changes
203
+
204
+ - 597df2e: re-introduce plugin for easy configuration, we're still publicly exporting all the pieces, so you can still continue to configure your server as you do today.
205
+
206
+ ```js
207
+ import { remixFastify } from "@mcansh/remix-fastify";
208
+ import { installGlobals } from "@remix-run/node";
209
+ import { fastify } from "fastify";
210
+
211
+ installGlobals();
212
+
213
+ let app = fastify();
214
+
215
+ await app.register(remixFastify);
216
+
217
+ let port = Number(process.env.PORT) || 3000;
218
+
219
+ let address = await app.listen({ port, host: "0.0.0.0" });
220
+ console.log(`✅ app ready: ${address}`);
221
+ ```
222
+
223
+ and if you need to configure loadContext, you can do so like this:
224
+
225
+ ```js
226
+ import { remixFastify } from "@mcansh/remix-fastify";
227
+ import { installGlobals } from "@remix-run/node";
228
+ import { fastify } from "fastify";
229
+
230
+ installGlobals();
231
+
232
+ let app = fastify();
233
+
234
+ await app.register(remixFastify, {
235
+ getLoadContext(request, reply) {
236
+ return {};
237
+ },
238
+ });
239
+
240
+ let port = Number(process.env.PORT) || 3000;
241
+
242
+ let address = await app.listen({ port, host: "0.0.0.0" });
243
+ console.log(`✅ app ready: ${address}`);
244
+ ```
245
+
246
+ ### Patch Changes
247
+
248
+ - 90c6c61: changeset for #324
249
+
250
+ bump dependencies to the latest versions
251
+
252
+ ## 3.2.2
253
+
254
+ ### Patch Changes
255
+
256
+ - 9300c22: feat: allow http2/https servers
257
+
258
+ previously using `fastify({ http2: true })` or `fastify({ https: {...} })` resulted in type errors for the handler when passing the request
259
+ ![image](https://github.com/mcansh/remix-fastify/assets/11698668/7a02b889-a9a9-4ddb-8686-ef6cda8d1bae)
260
+
261
+ this has been fixed by passing the server type to all uses of the request and reply internally
262
+ ![image](https://github.com/mcansh/remix-fastify/assets/11698668/ff23882b-c169-4b61-bc5f-90683c52fc1b)
263
+
264
+ this PR allows any server that extends `http.Server | https.Server | http2.Http2Server | http2.Http2SecureServer;`
265
+
266
+ ## 3.2.1
267
+
268
+ ### Patch Changes
269
+
270
+ - d11803a: remove `criticalCss` option from createRequestHandler as it's now handled by the vite plugin in an agnostic way
271
+
272
+ ## 3.2.0
273
+
274
+ ### Minor Changes
275
+
276
+ - a5ee9f1: add support for inlining criticalCss when using the vite plugin
277
+
278
+ ## 3.1.0
279
+
280
+ ### Minor Changes
281
+
282
+ - f6793b4: remove `staticFilePlugin` wrapper around `@fastify/static` as the example is now configured properly to find new files without colliding with remix routes
283
+
284
+ ### Patch Changes
285
+
286
+ - 8f3093e: update author info, add keywords and funding keys to package.json
287
+ - 25f00c3: bump dependencies to latest
288
+
289
+ ## 3.0.2
290
+
291
+ ### Patch Changes
292
+
293
+ - 9560ef1: fix: actually determind requested file
294
+ - 66ba8e5: move glob inside onRequest hook in order for getStaticFiles to be called. doing this allows the removal of node --watch which i totally didn't realize was restarting the server as we import the build 😅
295
+
296
+ ## 3.0.1
297
+
298
+ ### Patch Changes
299
+
300
+ - 1484ec4: Uses the normalized path for `filePublicPath`.
301
+
302
+ ## 3.0.0
303
+
304
+ ### Major Changes
305
+
306
+ - 40e8daa: remove plugin in favor of having server code in server. this allows live reload funcationally of `remix dev` to work
307
+
308
+ you can find an example of the updated server code in [/example/server.js](/example/server.js)
309
+
310
+ ### Minor Changes
311
+
312
+ - 40e8daa: remove references to fetch polyfills
313
+
314
+ ## 2.8.1
315
+
316
+ ### Patch Changes
317
+
318
+ - 4789835: add custom contentParser for json
319
+
320
+ fastify automatically configures `application/json` which prevents fethcer.submit from working with json encoding
321
+
322
+ ## 2.8.0
323
+
324
+ ### Minor Changes
325
+
326
+ - 31c3507: feat: require explicit `installGlobals` call in server entry
327
+
328
+ newer versions of node include `Request`, `Response`, `Headers`, `fetch`, etc globals
329
+
330
+ ## 2.7.4
331
+
332
+ ### Patch Changes
333
+
334
+ - b7e5567: chore: move @remix-run/router to deps, bump to latest
335
+
336
+ ## 2.7.3
337
+
338
+ ### Patch Changes
339
+
340
+ - c279e3a: return reply from response handler for async work (fastify/compression)
341
+
342
+ ## 2.7.2
343
+
344
+ ### Patch Changes
345
+
346
+ - ab24416: fix(plugin): return handler in production
347
+ - d92c468: automatically disable require cache purging when unstable_dev is truthy
348
+
349
+ ## 2.7.1
350
+
351
+ ### Patch Changes
352
+
353
+ - d3c16fb: feat: add support for early hints (HTTP 103)
354
+
355
+ ## 2.7.0
356
+
357
+ ### Minor Changes
358
+
359
+ - 31f5883: fix for post requests getting aborted
360
+
361
+ ## 2.6.4
362
+
363
+ ### Patch Changes
364
+
365
+ - c4bc305: Pass fastify-racing's AbortEvent on to AbortController
366
+
367
+ ## 2.6.3
368
+
369
+ ### Patch Changes
370
+
371
+ - 4f30f2a: ensure browserAssetUrl has a leading slash when it makes it to fastify
372
+
373
+ ## 2.6.2
374
+
375
+ ### Patch Changes
376
+
377
+ - 9337062: add leading slash to browserAssetUrl
378
+
379
+ ## 2.6.1
380
+
381
+ ### Patch Changes
382
+
383
+ - 4eef90e: fix: better windows file path support
384
+
385
+ ## 2.6.0
386
+
387
+ ### Minor Changes
388
+
389
+ - b52d31b: use tsup for building/bundling, no user facing changes
390
+
391
+ ## 2.5.0
392
+
393
+ ### Minor Changes
394
+
395
+ - 394c89c: Match static files in development based on the pathname to fix HMR.
396
+
397
+ ## 2.4.1
398
+
399
+ ### Patch Changes
400
+
401
+ - f3bdaa9: allow disabling purging of require cache
402
+
403
+ useful when using the `future.unstable_dev` remix config flag
404
+
405
+ ## 2.4.0
406
+
407
+ ### Minor Changes
408
+
409
+ - e2b4224: Make Remix root directory location configurable.
410
+
411
+ ## 2.3.1
412
+
413
+ ### Patch Changes
414
+
415
+ - a581f54: Fix Fetch Request creation for incoming URLs with double slashes
416
+
417
+ ## 2.3.0
418
+
419
+ ### Minor Changes
420
+
421
+ - 9fd5b94: feat: Stream results to clients
422
+
423
+ Instead of buffering the results and sending them down when they're all complete, instead we use a Passthrough stream to stream the chunks generated by Remix as we receive them.
424
+
425
+ ## 2.2.1
426
+
427
+ ### Patch Changes
428
+
429
+ - 342f8e9: fix: concat chunks for nested routes
430
+
431
+ ## 2.2.0
432
+
433
+ ### Minor Changes
434
+
435
+ - 805539b: properly use writeReadableStreamToWritable so that we use fastify's api for writing headers and the final response
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Logan McAnsh
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.