It's the little things: Three developer experience delights of our Remix authentication package


We integrate with a lot of React frameworks - here's what we love most about our Remix authentication package

Clerk is building authentication for the modern web. That means we don't just offer SDKs for different programming languages (Javascript, Ruby, Go), we offer SDKs for each modern React framework, too. We're proud to have first-class support for Next.js, Redwood, Gatsby, Expo, and – of course – Remix.

For every framework, we challenge ourselves to make Clerk's installation and usage as straightforward as possible. In this post, we highlight two developer experiences of our Remix authentication package that we absolutely love.

1. getAuth(request)

When handling a server-side request, there's only two theoretical ways developers can retrieve authentication data from Clerk.

First, with a wrapper function like withAuth():

const handler = withAuth(async (request) => {
  // withAuth adds the `auth` property to request
  const { auth } = request

Second, with a direct accessor like getAuth():

const handler = async (request) => {
  const auth = await getAuth(request);

Call us crazy, but we like getAuth(request) better. It feels more natural to access the data "just-in-time" instead of configuring it as a wrapper.

Fortunately, Remix enables us to provide this developer experience. After some upfront configuration in root.tsx, developers can use getAuth() in the loaders and actions of any route. It's really easy!

2. Splats ($.tsx)

We like to say splats are money.

Name a route $.tsx and it will serve all sub-routes. Clerk relies on this wildcard functionality when developers mount our components directly in their application.

Specifically, when a developer mounts <SignIn/> on the /sign-in route, we actually mount several sub-paths:

  • /sign-in - to start the process
  • /sign-in/factor-one - to verify the first factor
  • /sign-in/factor-two - to verify the second factor
  • /sign-in/verify - to handle magic links clicked in an email

These subpaths are nice because it helps us handle the refresh button. If a user is entering the second factor and they click the refresh button, we don't want them to lose their progress. Storing some state in the URL bar helps us provide the best possible user experience.

We love splats because their fun, intuitive, and easy. Next.js calls the same concept "Optional Catch-all Routes" and has the syntax /[[...slug]].tsx, which we find a little cumbersome in comparison.

3. Edge-by-default

We'd be remiss if we didn't include that Remix runs on the edge by default.

In this case, it's really the absence of code we're showing off. There is no "adding" edge support, it all just works.

This is great because Clerk is optimized for the edge. We include stateless authentication with JWTs in every plan, which are perfect for edge-based applications where georgraphy-bound network requests should be avoided. (Don't worry, our JWTs expire every minute so sessions are still revocable!)

The edge is the future, and we're thankful Remix's defaults will help speed up adoption and the web.

Colin Sidoti