Library / SDK
sergiodxa/remix-auth avatar
sergiodxa/remix-auth

remix-auth: the authentication layer that stays out of your way

Simple Authentication for Remix

2,202 stars108 forksTypeScriptMIT

At a glance

What is it?
A server-side strategy runner for Remix and React Router apps, with no runtime dependencies and a migration story that explains why community strategies are lagging behind.
Who is it for?
remix-auth holds its shape well: one class, a named strategy registry, and a hard rule that session storage and user records belong to the application. What deserves scrutiny is the pace.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 7, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A library with one narrow job

remix-auth describes itself as simple authentication for Remix, and the package description has since widened to cover React Router as well. At roughly 2,200 stars and a little over 100 forks under MIT, it occupies an unusual slot: not an identity provider, not a user store, and not a token manager. It is a runner. You give it named strategies, hand it a Request, and it calls the right one, then hands back whatever that strategy resolved to.

What sits in the repository is correspondingly small. The tree holds a `src/` directory, a `package.json`, a `bun.lock`, lint and formatting configuration, a TypeScript config, `typedoc.json` for the hosted API docs, and the usual community files. There is no `examples/` folder and no framework-specific scaffolding. That thinness is the design statement. The library takes a standard `Request`, runs a strategy, and returns a `Response`; everything else is delegated.

Passport's pattern rebuilt on the Fetch API

The README is explicit that the project is heavily inspired by Passport.js while being a rewrite built on top of the Web Fetch API rather than Node's `http` objects. That choice is the whole trick for a framework-agnostic auth runner. Because the contract is Request in, Response out, the same code works under Remix, React Router, or any other fetch-based server runtime.

Strategies live in separate npm packages, exactly as in the Passport ecosystem, and they are registered by name. Registering the form strategy as `user-pass` in the README example is not decoration: the name is the key the route action later passes to `authenticator.authenticate("user-pass", request)`. The same name can hold two different strategies, which is what makes one authenticator able to run, say, a GitHub flow and an OAuth 2.0 flow against the same provider without collisions. The v4.1.0 release added a way to fetch a registered strategy instance back out by name, and v4.2.0 loosened that method to accept a generic for the strategy type, which is the sort of refinement you only need if you intend to touch the instance directly.

Sessions and user records stay in your app

The most consequential decision in the README is what it declines to do. It shows the authenticator being constructed with a generic describing the shape of the user your strategies return, then shows session storage being created with React Router's `createCookieSessionStorage`, including `httpOnly`, `sameSite: "lax"`, a `path`, a secrets array, and `secure` tied to `NODE_ENV`. After `authenticate` resolves, the route action stores the result in the session and commits the cookie itself.

So the library owns exactly one moment: turning a request plus a strategy name into an identity value. Where that value is written, whether it is a full record or a bare token, how long the session lives, and whether you sign the cookie yourself are all application decisions. The README states this in plain language. The tradeoff is real and cuts both ways. You avoid an opinionated user model and an opinionated storage layer, which is valuable when your identity shape is unusual. You also inherit the full burden of session security, cookie sizing, and logout invalidation with no helper library to lean on.

package.json is the more useful document

Because the code is short, the manifest tells you most of the story. The runtime dependency list is empty. `type` is `module` and `sideEffects` is `false`, both of which matter for tree shaking. `engines` requires Node 20 or newer. The export map is deliberately minimal, exposing the root entry, a `./strategy` subpath for the strategy interface type, and `./package.json`.

The scripts section is where the project's actual habits show up:

json
	"scripts": {
		"build": "tsc",
		"typecheck": "tsc --noEmit",
		"lint": "oxlint .",
		"lint:fix": "oxlint . --fix",
		"format": "prettier . --check",
		"format:fix": "prettier . --write",
		"exports": "bun run ./scripts/exports.ts"
	},

Two details stand out. Linting runs on oxlint rather than ESLint, which is why the repository carries `.oxlintrc.json` instead of an ESLint config, a migration that removes the heaviest dev dependency most projects drag around. And the `exports` script runs a TypeScript file through Bun to regenerate the export map, meaning the manifest is partly generated output that a maintainer is expected to re-run rather than hand-edit.

Note also that the published `files` array includes `src` alongside `build`, shipping sources for source maps and tooling, and the lockfile is `bun.lock` even though the documented install path is npm. Both are minor, but they tell you the maintainer's local loop is Bun.

The v4 reset and the ecosystem it left behind

Version 4.0.0 shipped in late November 2024 with two changes that matter more than the feature list suggests: modernizing the package setup, and dropping what the notes call the RR requirement while simplifying the library considerably. The same release carries a community contribution titled as an upgrade from Remix v2 to React Router v7.

That is a genuine breaking change to anyone extending the library or depending on an internal that used to be re-exported, and it is precisely the kind of event that strands small packages. The README anticipates this with a callout telling integrators to check each strategy for which versions of remix-auth it supports, since strategies may not be updated to the newest release. Every named strategy is maintained as a separate repository with its own maintainer and its own release schedule. A major version here is only useful if the community packages move with it.

The cadence since then is unhurried. v4.1.0 landed December 2024 with the strategy-instance accessor, and v4.2.0 landed April 2025 with the generic accessor plus documentation work on passing extra data through `AsyncLocalStorage` and on writing custom strategies against the current API. Meanwhile the default branch has been pushed as recently as late September 2026. The gap between active commits and a tagged release is the practical thing to track if you are pinning versions in a lockfile.

Tooling gaps worth naming

The dev dependency list is a good place to look for loose ends. `@arethetypeswrong/cli` and `msw` are both declared as development dependencies, and neither is referenced by any entry in the scripts object. There is no test script at all, no test runner, and no coverage command. The original upstream used to carry those suites; the current repository does not wire them up.

This is worth stating plainly rather than dressing up. The build is a TypeScript compile, the typecheck is the same compile with emit disabled, lint and format are enforced, and API docs are generated by TypeDoc with an MDN link plugin that feeds the GitHub Pages site. What is missing is any automated assertion that a strategy still authenticates, or that the package still publishes the shape consumers expect. The open issue count of three is consistent with a small, well-run project rather than an abandoned one, but it does not substitute for a test suite. If you adopt this library, your own integration test that exercises a real login round trip through your routes is not optional polish; it is the safety net the project does not provide.

Where the boundary sits

Three things the library deliberately leaves outside its scope come up in nearly every evaluation. Authorization is the first: remix-auth answers who is calling, not whether that caller may perform the operation, so role checks belong in loaders and actions. CSRF protection is the second; it comes from your form and cookie configuration rather than from this package. The third is rate limiting on credential submission, which is entirely on the strategy side, and matters most for the form strategy where password verification is local to your code.

A second boundary is size. The README's example stores the whole user object in a cookie session, which is fine for a handful of fields and quietly wrong for a fat profile object. Cookie sessions are transported on every request and signed, not encrypted, so anything sensitive belongs on the server. Beyond that, remember that strategies resolve to whatever your verify callback returns. If that value is an access token with a short life, the session will outlive the credential, and refreshing becomes your problem to solve.

Comparisons in the wild tend to frame the choice as library versus a broader framework such as Better Auth, which ships its own data layer and a plugin system. The honest framing is narrower. remix-auth is the piece you reach for when you want a familiar strategy registry and control over identity storage, and it is the piece you skip when you would rather not write session code at all.

Editorial conclusion

remix-auth holds its shape well: one class, a named strategy registry, and a hard rule that session storage and user records belong to the application. What deserves scrutiny is the pace. The last tagged release is v4.2.0 from April 2025 while the branch has been pushed through late September 2026, and the package ships dev tooling that no script invokes. Treat it as a stable primitive with an active, if slow, release cadence, and pin your strategy packages deliberately, because the v4 break is exactly where version drift bites.

Frequently asked questions

What does remix-auth actually do inside a Remix application?

It runs a named authentication strategy for you. You register strategies on an Authenticator instance, then call authenticate with the strategy name and the incoming request; the strategy validates the request and returns whatever your verify callback produces. Storing that result in a session, and creating the session itself, stays in your application code.

Does remix-auth have any runtime dependencies?

None are declared. The manifest lists only dev dependencies, so the package adds no transitive weight to your bundle. That is also why it can sit on top of the Web Fetch API rather than a specific server runtime, and why it works under both Remix and React Router without a second build.

How compatible is remix-auth with React Router 7?

The v4.0.0 release carried an upgrade from Remix v2 to React Router v7 and dropped a prior runtime requirement, and the package description now names both frameworks. The package also requires Node 20 or newer. Community strategies are separate repositories, so check each one for the versions of remix-auth it declares before upgrading.

Does remix-auth store user records or passwords itself?

No. Your strategy's verify callback decides what a successful login returns, and the library never persists it. Password verification for the form strategy happens in code you write, which means hashing, timing-safe comparison, lockout policy and rate limiting are all your responsibility. The example session stores the returned value in a cookie, so keep it small and non-sensitive.

How often is remix-auth released, and what is the current version?

The current tag is v4.2.0, published in April 2025, following v4.1.0 in December 2024 and the v4.0.0 major in late November 2024. The default branch has been pushed well past that date, so commits and tags move at different speeds. If you pin a version in a lockfile, plan for the next major to include the community strategy updates.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. sergiodxa/remix-auth on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sergiodxa-remix-auth.svg)](https://hysenlabs.com/projects/sergiodxa-remix-auth)