Quickstart
Get your first login working in under five minutes. You need Node.js 18+ and a Postgres database.
Install
npm install own-authSet Your Environment Variables
Add your Postgres connection string and token pepper to your environment.
DATABASE_URL=postgres://user:password@localhost:5432/myapp
OWN_AUTH_TOKEN_PEPPER=your-random-secret-stringThe token pepper adds an extra layer of protection to hashed tokens in your database. Generate a long random string and keep it secret.
Any Postgres database works: local, hosted, Supabase, Neon, Railway, or RDS. Own Auth creates its own tables and does not modify yours.
Run Migrations
npx own-auth migrateThis creates the tables Own Auth needs: users, sessions, tokens, organisations, API keys, and audit logs. Your existing tables are not modified.
Run this once during setup.
Verify the database connection and migration version:
npx own-auth statusCreate Your Auth Instance
Create an auth.ts file in your project. This is the single entry point for all auth operations.
import { createOwnAuth } from "own-auth";
export const auth = createOwnAuth({
tokenPepper: process.env.OWN_AUTH_TOKEN_PEPPER,
session: {
ttlMs: 30 * 24 * 60 * 60 * 1000, // 30 days
},
});That is your auth layer. Every function in this guide is called on this auth instance. Own Auth reads DATABASE_URL automatically.
Sign Up A User
const { user, session, sessionToken } = await auth.signUpEmailPassword({
email: "alice@example.com",
password: "her-secret-password",
name: "Alice",
});
// user.id -> "usr_a1b2c3..."
// user.email -> "alice@example.com"
// user.name -> "Alice"
// sessionToken -> send this to the client securely
// session.expiresAt -> 2026-08-09T...The password is hashed before it is stored. Own Auth never saves plain-text passwords. The session is created automatically, so the user is signed in as soon as they sign up.
If the email is already taken, signUpEmailPassword throws a typed error you can catch and handle:
import { AuthError } from "own-auth";
try {
const { user, session, sessionToken } = await auth.signUpEmailPassword({
email,
password,
name,
});
} catch (error) {
if (error instanceof AuthError && error.code === "email_already_exists") {
// Handle the duplicate email.
}
throw error;
}Sign In
const { user, session, sessionToken } = await auth.signInEmailPassword({
email: "alice@example.com",
password: "her-secret-password",
});
// sessionToken -> send this to the client securely
// session.userId -> "usr_a1b2c3..."
// session.expiresAt -> 2026-08-09T...The session token identifies the user on future requests. Send it to the client as a cookie, a header, or however your application handles tokens.
If the credentials are wrong, signInEmailPassword throws AuthError with the code invalid_credentials. The error deliberately does not reveal whether the email or password was wrong.
Verify A Session
On every authenticated request, verify the session token to identify the user.
const result = await auth.getCurrentSession(sessionToken);
if (!result) {
// Not signed in. Return 401.
}
// result.session.userId -> "usr_a1b2c3..."
// result.user -> { id, email, name, ... }getCurrentSession checks the token against the database. If the session is expired or has been revoked, it returns null.
Sign Out
await auth.signOut(sessionToken);The session is revoked immediately. The token stops working on the next request.
Full Example
Here is everything together in a minimal script. No framework, just plain TypeScript. Swap in Express, Hono, Fastify, or whatever you use.
import { auth } from "./auth";
// Sign up.
const { sessionToken } = await auth.signUpEmailPassword({
email: "alice@example.com",
password: "her-secret-password",
name: "Alice",
});
// Send sessionToken to the client as a cookie, header, or another secure value.
// Later, verify the session on an incoming request.
const result = await auth.getCurrentSession(sessionToken);
if (result) {
console.log("Signed in as", result.user.email);
}
// Sign out.
await auth.signOut(sessionToken);That is it. Users, passwords, and sessions are working. Everything is in your Postgres database, under your control.
What's Next
You have basic email/password auth. Here is where to go next:
Auth methods: Add passwordless login with magic links, or phone-based login with SMS verification.
Sessions: Learn how session management works, including revoking sessions across devices.
Organisations: Add teams, roles, and invitations for multi-tenant applications.
API access for integrations: Issue scoped application API keys for programmatic access to your application's API.
Email delivery: Set up your own email provider, or use Own Auth Delivery to send magic links, verification emails, and invitations without configuring SMTP.
Security: Read the security model to understand hashing, token expiry, rate limiting, and audit logs.
Framework guides: See integration guides for Next.js, Express, Hono, and Fastify.