Introducing Lucia: A simple, flexible, and type-safe authentication library for Next.js, SvelteKit, and beyond
Tags: nextjs, javascript, svelte, security
Published: 2022-11-07 11:50:30

Hi!

Over the past few months, I've been working on a library called [Lucia](https://github.com/pilcrowOnPaper/lucia-auth). 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](https://lucia-auth.vercel.app/nextjs/start-here/getting-started), [SvelteKit](https://lucia-auth.vercel.app/sveltekit/start-here/getting-started), and [Astro SSR](https://lucia-auth.vercel.app/astro/start-here/getting-started). We also have a package for handling [OAuth](https://lucia-auth.vercel.app/oauth/start-here/getting-started). 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

```ts
// 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);
```

### Validate requests

```ts
// will also renew sessions if expired
const session = await auth.validateRequest(request, setSession);
```

Or using Next.js integration:

```ts
const authRequest = new AuthRequest(auth, ctx.req, ctx.res);
const session = await authRequest.getSession();
```

### OAuth

```ts
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;
});
```

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