<arch.design/>
primitivesself-hostedMonolithopen source

Lucia

Minimal session management primitives — you control the auth logic

lucia-auth.com

Overview

Lucia is a minimal, framework-agnostic session management library. It deliberately does NOT handle password hashing, OAuth flows, or token generation — it only manages sessions and their lifecycle. You write the auth logic; Lucia handles the session store.

The Lucia author (pilcrowOnPaper) has since sunset active development and now recommends reading the Lucia source as educational material and writing session management yourself. However, the existing library remains stable and production-worthy.

For greenfield projects, the author's newer library oslo provides cryptographic primitives (PKCE, HMAC, password hashing) that you assemble yourself — the "build your own auth" approach with solid primitives.

Architecture fit

self-hostedMonolith

Best suited to run inside your main application process alongside your app logic and database.

Key features

Session CRUD with automatic expiry and rolling sessions
Adapters for every major database (Prisma, Drizzle, MySQL, Postgres, Redis…)
Framework adapters (Next.js, SvelteKit, Astro, Hono…)
Typed session attributes — extend with any fields
Cookie-based or Bearer token session storage
oslo companion library for OAuth, PKCE, HOTP, password hashing

Trade-offs

+

Complete control — you write every auth decision

More code to write — no OAuth or password handling built in

+

Tiny footprint, no magic, easy to audit

Actively sunset by author — consider it in maintenance mode

+

Best for learning how auth works under the hood

No organizations, 2FA, or passkeys without building them

+

Works everywhere Node.js runs

Smaller plugin/community ecosystem than Auth.js or Better Auth

When to use

  • You want to deeply understand session management
  • Custom auth flows that no framework handles well
  • SvelteKit or Astro apps where Auth.js support is limited
  • Teams who value simplicity over features

When NOT to use

  • Production apps starting today — Better Auth covers the same ground with more features
  • Need OAuth, 2FA, or passkeys without writing them yourself
  • Large teams who need a maintained, feature-rich solution

Implementation

TypeScript
// lib/lucia.ts
import { Lucia } from "lucia";
import { PrismaAdapter } from "@lucia-auth/adapter-prisma";

export const lucia = new Lucia(new PrismaAdapter(prisma.session, prisma.user), {
  sessionCookie: { attributes: { secure: process.env.NODE_ENV === "production" } },
  getUserAttributes: (attrs) => ({ email: attrs.email, username: attrs.username }),
});

// Register — hash password yourself (use oslo/password)
import { Argon2id } from "oslo/password";
const hash = await new Argon2id().hash(password);
await prisma.user.create({ data: { email, passwordHash: hash } });
const session = await lucia.createSession(user.id, {});
const cookie = lucia.createSessionCookie(session.id);

// Middleware — validate session on every request
const sessionId = lucia.readSessionCookie(req.headers.get("cookie") ?? "");
if (!sessionId) return new Response(null, { status: 401 });
const { session, user } = await lucia.validateSession(sessionId);
if (!session) return new Response(null, { status: 401 });

// Rolling session — extend expiry on activity
if (session.fresh) {
  res.headers.set("Set-Cookie", lucia.createSessionCookie(session.id).serialize());
}

In production

Community projects

Popular in SvelteKit and Astro communities for custom auth setups

Educational codebases

Widely used in auth tutorials for teaching session management fundamentals

Other frameworks

← Back to Authentication