DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

pilcrowOnPaper
pilcrowOnPaper

Posted on

Introducing Lucia: A simple, flexible, and type-safe authentication library for Next.js, SvelteKit, and beyond

Hi!

Over the past few months, I've been working on a library called Lucia. At its core, it's a user and session management library that provides an abstraction layer between your app and your database. Using it, you can create users, creates sessions for those users, and validate those sessions. But, it doesn't try to do more than that; you have to create your own sign-in forms and APIs, and handle things like email verification by yourself. But, because of that, how you use Lucia is totally up to you.

That said though, we do provide integration packages to make it easier to use with your favorite frameworks. Right now, we directly support Next.js, SvelteKit, and Astro SSR. We also have a package for handling OAuth. I think it's important to keep the core package simple and focused, and give you the option to trade some flexibility for an easier experience. It shouldn't be the other way around.

And this is what makes it different from existing solutions like Supabase auth, SuperTokens, or NextAuth. It isn't a complete solution, and it never tries to be so. It allows you to make something that fits your app's need and build on top of it. There's no hidden configurations or callbacks that forces you to use jank solutions.

Repo: https://github.com/pilcrowOnPaper/lucia-auth

Docs: https://lucia-auth.vercel.app

Features!

Aside from the obvious (own your data, secure, MIT license, etc):

Supports any databases

We take a similar approach to NextAuth, where we provide database adapters. We currently provide adapters for Prisma, Supabase, MongoDB, and Redis. We also have an extensive documentation on creating your own adapters and provide a package for testing them.

Custom user attributes

Similar to Firebase custom claims, you can set any user attributes to the user. By default, only the user id is required to be stored in your database, and you can add additional columns to it (like username, is_verified, etc).

Low-level control

Since Lucia is the layer between your database and app, it provides everything you need to interact with user and session data. Just a single method to update user data and password, invalidate sessions, create session cookies, etc.

Session ids

This is less a feature but more of the inner-workings. To not over-complicate the APIs, we only support session ids (and not JWTs). While JWT + access/refresh tokens may be a better fit in some use cases, we think you can't go wrong using session ids.

Code samples

Create user and session

// create a user using "email" auth method
const user = await auth.createUser("email", userEmail, {
  password: userPassword, // will hash it for you
  attributes: {
    username: userUsername
  }
});
const session = await auth.createSession(user.userId);
const sessionCookies = auth.createSessionCookies(session);
Enter fullscreen mode Exit fullscreen mode

Validate requests

// will also renew sessions if expired
const session = await auth.validateRequest(request, setSession);
Enter fullscreen mode Exit fullscreen mode

Or using Next.js integration:

const authRequest = new AuthRequest(auth, ctx.req, ctx.res);
const session = await authRequest.getSession();
Enter fullscreen mode Exit fullscreen mode

OAuth

const callbackCode = url.searchParams.get("code");
const { existingUser, providerUser, createUser } = await githubAuth.validateCallback(callbackCode);
// create a new user for first-time users
const user = existingUser || (await createUser({
  username: providerUser.login;
});
Enter fullscreen mode Exit fullscreen mode

If you have any questions while using Lucia, feel free to ask us on GitHub or Discord. Cheers!

Top comments (5)

Collapse
 
gevera profile image
Denis Donici • Edited on

How would one go about using Lucia in Sveltekit with already existing backend that already provides authorization with JWT lets, say Strapi or Directus

Collapse
 
pilcrowonpaper profile image
pilcrowOnPaper

I’m assuming Strapi is a CMS and Directus is a database? You can check for the session in the server using Lucia, and fetch some data based on it.

Collapse
 
gevera profile image
Denis Donici

Directus is a CMS as well. They both generate JWTs for authentication

Collapse
 
kolja profile image
Kolja

Yea, i`m very interested in an example of this too.

Collapse
 
plckr profile image
Ricardo Reis

Hasura follows the same principle I guess, and I don't know how I could implement it

Join us at DEV
Yes, this is technically an β€œad”, but really we just want to ask if you want to join DEV. We have 900k+ developers reading, posting, and enjoying community, and would love to have you. Β  Create an account and continue your coding journey.