Change8

remix@3.0.0-beta.1

Breaking Changes
📦 remixView on GitHub →
8 breaking3 features1 deprecations🔧 50 symbols

Summary

This pre-release introduces major breaking changes focused on modularizing exports, updating context derivation patterns using `MiddlewareContext`, and standardizing controller file locations to `app/actions`. It also integrates Remix's internal `node-tsx` loader for testing and execution.

⚠️ Breaking Changes

  • Removed the `ContextWithAuth` and `ContextWithRequiredAuth` helper types from `remix/auth-middleware`. Derive auth-aware request context from the actual auth middleware tuple with `MiddlewareContext`, or use the core `ContextWithEntry` helper from `remix/fetch-router` when manually composing context types without a middleware tuple.
  • Remix app scaffolding, `remix doctor`, and `remix routes` now use `app/actions` with controller files only. The old `app/controllers` directory name has been replaced by `app/actions`, and root route actions should no longer live in standalone files. Move route controllers from `app/controllers` to `app/actions`, consolidate root route actions into `app/actions/controller.tsx`, and map nested route maps explicitly in `app/router.ts` with one `router.map(...)` call per route map.
  • Removed the `ContextWithRenderer` helper type from `remix/render-middleware`. Derive renderer-aware request context from the `renderWith()` middleware tuple with `MiddlewareContext`, or use the core `ContextWithEntry` helper from `remix/fetch-router` when manually composing context types without a middleware tuple.
  • `remix test` and `remix/test` now use Remix's internal `node-tsx` loader instead of the `tsx` package.
  • `remix/async-context-middleware` no longer exposes `AsyncContextTypes`. `getContext()` now derives its type from `remix/fetch-router`'s `RouterTypes.context`, with route params broadened to `AnyParams`, so apps only need the router context augmentation.
  • Updated the re-exported `remix/fetch-router` helper types around full request-context types and stored route handlers. `Action`, `Controller`, and `RequestHandler` now take the full request context type, `MiddlewareContext` accepts middleware values plus an optional base context, and `createAction()`/`createController()` are the preferred helpers for stored handlers. Low-level context transform helpers such as `BuildAction`, `MiddlewareContextTransform`, `ContextTransform`, `ApplyContextTransform`, `ApplyMiddleware`, and `ApplyMiddlewareTuple` are no longer exported. Use `ContextWithParams`, `ContextWithEntry`, `ContextWithEntries`, `MiddlewareContext`, and `RouteEntry` when manually composing request context or custom matcher payloads.
  • In `remix/route-pattern`, remove the `compareFn` parameter from `match` and `matchAll`. Matches always sort by specificity (most specific first). If you need a different order, sort the result of `matchAll` yourself.
  • New modular `remix/route-pattern` APIs and subpath exports. The base `remix/route-pattern` export now focuses on parsing and serializing route patterns.

Migration Steps

  1. When deriving auth-aware request context, use `MiddlewareContext` with the auth middleware tuple, or use `ContextWithEntry` from `remix/fetch-router`.
  2. Move route controllers from `app/controllers` to `app/actions`, consolidate root route actions into `app/actions/controller.tsx`, and map nested route maps explicitly in `app/router.ts` with one `router.map(...)` call per route map.
  3. When deriving renderer-aware request context, use `MiddlewareContext` with the `renderWith()` middleware tuple, or use `ContextWithEntry` from `remix/fetch-router`.
  4. To run `.ts`, `.tsx`, and `.jsx` files directly in Node.js, use `node --import remix/node-tsx`.
  5. Configure `RouterTypes.context` once and let `createController()` infer route action context from the route map and controller middleware.
  6. If sorting matches by specificity ascending was previously used, now call `matcher.matchAll(url).sort(Specificity.ascending)`.
  7. Use subpath exports for route pattern features: `remix/route-pattern/href`, `remix/route-pattern/match`, `remix/route-pattern/join`, or `remix/route-pattern/specificity` instead of importing them from the base `remix/route-pattern`.
  8. Update imports to use domain-oriented exports, e.g., change `import { ... } from 'remix/auth-middleware'` to `import { ... } from 'remix/middleware/auth'`.

✨ New Features

  • Expose `@remix-run/node-tsx` through `remix/node-tsx` and `remix/node-tsx/load-module`.
  • Added support for middleware-installed direct request context properties through `remix/fetch-router`, including the new `ContextEntry` type for object-shaped context entries.
  • Expose the `node-serve` `setup(app)` option through `remix/node-serve` so apps can register native uWebSockets.js WebSocket routes and connection filters before the Fetch fallback route starts listening.

Affected Symbols

⚡ Deprecations

  • Existing 1:1 package exports remain available during the beta migration and will be removed before a Remix 3.0.0 stable release.