Minor Changes
-
Mixins created through
remix/componentcan usecreateMixin(setup, { ssr: false })to skip setup and render on the server while keeping browser behavior and hydration. Server rendering remains enabled by default. The option is intended for behavior that does not contribute to the server HTML. (#12019) -
Server rendering with
remix/componentis about twice as fast as in 3.0 and uses less memory, with no code changes. Rendering a 48-product listing page withrenderToString()takes 244 µs instead of 513 µs (Node.js 24.18 on an Apple M5 Pro, median of 5 fresh-process runs, identical HTML output). Under sustained HTTP load on a 24-product store page, assembling each response with a single join lowers the server's resident memory after load from 793 MiB to 527 MiB (see #12006, #12016, #12018, and #12020). (#12074)Apps that render client entries also benefit from
getScriptEntry()caching inremix/assets: a warm lookup takes about 3 µs instead of 210 µs (see #12005). See the@remix-run/componentand@remix-run/assetschangelogs for details. -
Use
frame.reload({ src, method, encType, body })fromremix/componentto reload another source or submit data and render the response without changing browser history.FormDatafollows GET query and POST encoding defaults, with multipart and plain-text encodings available. (#11938) -
Prefetch frame HTML and assets with
data-rmx-prefetch="intent",data-rmx-prefetch="viewport", or the imperativeprefetch()API fromremix/component. Both link modes support named frames and source overrides, respect Save-Data, and skipslow-2g/2gconnections. See the prefetching guide for usage, customization, and caching behavior. (#12004) -
Opt out of automatic focus resets during intercepted navigation with
resetFocus: 'manual'innavigate()andlink(), ordata-rmx-reset-focus="manual"on links, forms, and submit buttons. Scroll and focus controls inremix/componentnow accept the Navigation API values"after-transition"(the default) and"manual"; existing boolean values remain supported. (#11939) -
remix/file-storage/s3now streams files to S3 with multipart uploads instorage.set(), so large files no longer need to fit in memory. A newpartSizeoption controls the size of each part. See the@remix-run/file-storage-s3changelog for details. (#12070) -
Add
remix/multipart-parser/future,remix/form-data-parser/future, andremix/middleware/form-data/future, which stream multipart parts and file uploads instead of buffering them in memory. Future APIs are not stable and may change in any release, but they are a good indication of where these packages will land in Remix's next major release. (#12030)In our benchmarks, parsing a request with a 100 MiB file upload takes 37 ms instead of 68 ms, the upload handler is called after 0.2 ms instead of 45 ms, and peak memory grows by 29 MiB instead of 396 MiB. Small forms perform the same as before. See the
@remix-run/form-data-parserchangelog for the full comparison.To try it in an app, import
formData()from the/futureentrypoint. Its options are the same as the stable middleware:-import { formData } from 'remix/middleware/form-data' +import { formData } from 'remix/middleware/form-data/future' export const router = createRouter({ middleware: [ formData({ async uploadHandler(upload) { let key = crypto.randomUUID() await storage.set(key, upload) return key }, }), ], })
Each upload streams from the request body, so read it inside
uploadHandler(for example by passing it tostorage.set()). It can be read only once,upload.sizeis not available until it has been read, andupload.slice()is not supported. Uploads the handler returns unread are read into a regularFile. Paired with the new streamingset()inremix/file-storage/s3, large uploads go straight to S3 without being held in memory.If your app handles file uploads, please give these entrypoints a try and tell us how it goes in GitHub Discussions. We'd especially like to hear about anything that breaks, behaves unexpectedly, or feels awkward, since that feedback will shape the next major release.
-
The
remix/*entrypoints now preserve default exports from their underlying packages, including the callable assertion helper fromremix/assertandSuperHeadersfromremix/headers. (#12061)Added
package.jsonexports:remix/form-data-parser/futureto re-export APIs from@remix-run/form-data-parser/futureremix/middleware/form-data/futureto re-export APIs from@remix-run/form-data-middleware/futureremix/multipart-parser/futureto re-export APIs from@remix-run/multipart-parser/future
Patch Changes
-
Ensure client entries requested after an HMR update use current cache-busting URLs. (#11980)
-
Include
unsafeHTML()guidance inremix/componentraw HTML prop errors (innerHTML,srcDoc, andsrcdoc) and clarify thatouterHTMLis not supported on host elements. (#11988) -
Bumped
@remix-run/*dependencies:assets@1.0.1cli@1.0.1component@1.1.0compression-middleware@1.0.1cookie@1.0.1cors-middleware@1.0.1fetch-proxy@1.0.1file-storage-s3@1.1.0form-data-middleware@1.1.0form-data-parser@1.1.0headers@1.0.1multipart-parser@1.1.0render-middleware@1.0.1response@1.0.1session-middleware@1.0.1spa@1.0.1static-middleware@1.0.1tar-parser@1.0.1