Auth0 charges $23/month for 1,000 users. Clerk starts at $25/month. Lucia gives you production-ready authentication for free — and you own every line of code.
What Is Lucia?
Lucia is a lightweight, session-based authentication library for TypeScript. It's not a service or a framework — it's a set of primitives that you compose into your auth system.
Why Not Use Auth-as-a-Service?
| Lucia | Auth Services | |
|---|---|---|
| Cost at 10K users | $0 | $100-500/month |
| Data ownership | You own everything | Vendor lock-in |
| Customization | Full control | Limited to their UI |
| Vendor risk | None | Service shutdown = disaster |
| Session storage | Your database | Their infrastructure |
Quick Start
npm install lucia
import { Lucia } from "lucia";
import { DrizzlePostgreSQLAdapter } from "@lucia-auth/adapter-drizzle";
const adapter = new DrizzlePostgreSQLAdapter(db, sessionTable, userTable);
export const lucia = new Lucia(adapter, {
sessionCookie: {
attributes: {
secure: process.env.NODE_ENV === "production"
}
},
getUserAttributes: (attributes) => ({
email: attributes.email,
name: attributes.name
})
});
Create User & Session
import { generateIdFromEntropySize } from "lucia";
import { hash } from "@node-rs/argon2";
async function signup(email: string, password: string) {
const userId = generateIdFromEntropySize(10);
const passwordHash = await hash(password);
await db.insert(userTable).values({
id: userId,
email,
password_hash: passwordHash
});
const session = await lucia.createSession(userId, {});
const cookie = lucia.createSessionCookie(session.id);
return cookie;
}
Validate Sessions
async function validateRequest(request: Request) {
const sessionId = lucia.readSessionCookie(
request.headers.get("Cookie") ?? ""
);
if (!sessionId) return { user: null, session: null };
const result = await lucia.validateSession(sessionId);
return result;
}
OAuth Integration
import { GitHub } from "arctic";
const github = new GitHub(
process.env.GITHUB_CLIENT_ID!,
process.env.GITHUB_CLIENT_SECRET!
);
// Generate authorization URL
const [url, state] = await github.createAuthorizationURL(["user:email"]);
// Handle callback
const tokens = await github.validateAuthorizationCode(code);
Framework Support
- Next.js — App Router + Pages Router
- SvelteKit — native integration
- Astro — middleware support
- Express/Hono — manual integration
- Nuxt — community adapter
Key Features
- Zero vendor lock-in — it's a library, not a service
- Database agnostic — PostgreSQL, MySQL, SQLite, MongoDB
- OAuth helpers via Arctic — GitHub, Google, Discord, 20+ providers
- CSRF protection built-in
- TypeScript-first with full type inference
Get Started
- Documentation
- GitHub — 9K+ stars
- Examples
Building an app with authentication? My web scraping tools on Apify can help you gather competitive intelligence data. Need a custom solution? Email spinov001@gmail.com
Top comments (0)