Authentication

User authentication with Better Auth

Authentication

Eden Stack uses Better Auth for authentication, integrated with Drizzle ORM for session storage.

How It Works

Better Auth is configured in @eden/auth with:

  • Drizzle adapter - Sessions stored in your Supabase database
  • Email/password - Enabled by default
  • 7-day sessions - With daily refresh and 5-minute cookie cache

Configuration

The auth package (packages/auth/src/index.ts) exports a pre-configured instance:

import { auth } from "@eden/auth";

Required environment variables:

BETTER_AUTH_SECRET=your-32-char-secret  # Session encryption
BETTER_AUTH_URL=http://localhost:3000   # Your app URL

Server-Side: Checking Sessions

In your Elysia API routes, check authentication using auth.api.getSession:

import { auth } from "@eden/auth";
 
app.get("/api/me", async ({ request, set }) => {
  const session = await auth.api.getSession({
    headers: request.headers,
  });
 
  if (!session) {
    set.status = 401;
    return { error: "Unauthorized" };
  }
 
  return { user: session.user };
});

Client-Side: Auth Forms

Better Auth provides a client SDK. Create auth forms in your TanStack Start app:

import { createAuthClient } from "better-auth/react";
 
const authClient = createAuthClient({
  baseURL: import.meta.env.VITE_API_URL,
});
 
// Sign up
await authClient.signUp.email({
  email: "user@example.com",
  password: "securepassword",
  name: "John Doe",
});
 
// Sign in
await authClient.signIn.email({
  email: "user@example.com",
  password: "securepassword",
});
 
// Sign out
await authClient.signOut();

Protected Routes

Create a route guard for authenticated pages:

// src/routes/_authenticated.tsx
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getApiClient } from "@/lib/api";
 
export const Route = createFileRoute("/_authenticated")({
  beforeLoad: async () => {
    const api = getApiClient();
    const { data, error } = await api.api.me.get();
    
    if (error || !data?.user) {
      throw redirect({ to: "/login" });
    }
    
    return { user: data.user };
  },
});

Then nest protected routes under _authenticated/:

src/routes/
├── _authenticated/
│   ├── dashboard.tsx    # Protected
│   └── settings.tsx     # Protected
├── login.tsx            # Public
└── index.tsx            # Public

Session Types

The auth package exports TypeScript types:

import type { Session, User } from "@eden/auth";

Next Steps

Full documentation for Eden Stack users

This documentation is exclusively available to Eden Stack customers. Already purchased? Log in to access the full content.