⚡ BolkAuth

BolkAuth is split into small packages with a clear boundary between authentication logic and framework/database integrations.

Architecture

React UI
  -> @bolkauth/react hooks
  -> /api/auth/* route handler
  -> @bolkauth/core
  -> BolkAuthAdapter
  -> Your database

Next.js middleware
  -> verifies the signed session cookie
  -> redirects unauthenticated requests

Core Engine

@bolkauth/core owns the authentication behavior:

AreaResponsibility
Email/passwordValidate credentials, hash passwords, create users and sessions.
Magic linksCreate verification tokens and verify emailed links.
OTPGenerate numeric codes, store hashed tokens, verify one-time use.
OAuthRedirect to providers, validate state, exchange codes, link accounts.
SessionsSign JWT cookies and persist session records through the adapter.
MetadataStore onboarding and custom user metadata through adapter methods.

Adapter Boundary

BolkAuth does not own your database client. The adapter is the only database contract the core engine needs:

export const auth = createBolkAuth({
  adapter: createDrizzleAdapter(db),
  secret: process.env.BOLKAUTH_SECRET!,
});

That boundary lets you use Drizzle, Prisma, MongoDB, or your own storage implementation.

Session Model

After a successful sign-in, BolkAuth:

  1. Creates a database session through adapter.createSession.
  2. Signs a JWT containing sessionId and userId.
  3. Sends the JWT in an HttpOnly cookie.
  4. Uses the cookie on future requests to read the current session.

The cookie is not readable by client-side JavaScript. React hooks call the auth API to load the current user and session.

Request Flow

POST /api/auth/sign-in/email
  -> validate email and password
  -> find user by email
  -> verify password hash
  -> create session
  -> set bolkauth.session cookie
  -> return user and session data

For protected pages, middleware checks the cookie before rendering and redirects unauthenticated users to signInUrl.

Cross-Tab Sync

BolkAuthProvider uses BroadcastChannel to refresh auth state in every open tab after sign-in, sign-up, and OTP verification. Client components do not need to poll for auth changes.

Errors

API responses use a consistent shape:

interface BolkAuthResponse<T> {
  data?: T;
  error?: {
    code: string;
    message: string;
    fieldErrors?: Record<string, string[]>;
  };
}

Common codes include invalid_credentials, user_exists, weak_password, invalid_email, invalid_otp, otp_not_configured, oauth_error, and unauthorized.

On this page