Guidelines for writing Svelte apps with Better Auth Authentication
Provides a Svelte store, auth guard, and component pattern for integrating Better Auth authentication into a SvelteKit app.
What this file does
Provides a Svelte store, auth guard, and component pattern for integrating Better Auth authentication into a SvelteKit app.
When to use it
- Adding Better Auth to a new or existing SvelteKit project
- Implementing protected routes with authentication guards
- Managing authentication state with Svelte stores
- Setting up OAuth providers like Google and GitHub
Assumes this stack
title: "Guidelines for writing Svelte apps with Better Auth Authentication" description: "Bootstrap Svelte app with Better Auth Authentication" tags: ["Svelte", "Better Auth", "Integration", "Setup", "Frontend"] category: "Coding" author: "Csaba Farkas" slug: "guidelines-for-writing-svelte-apps-with-better-auth-authentication" id: "coding-87" seo_keywords: "Svelte Better Auth integration, Better Auth setup, Svelte authentication, SvelteKit auth, Secure authentication" date: "2025-07-13" difficulty: "Advanced" schema_type: "TechArticle"
Guidelines for writing Svelte apps with Better Auth Authentication
Bootstrap Svelte app with Better Auth Authentication
Overview of implementing Better Auth Authentication
- Install better-auth package
- Set up environment variables
- Create a Better Auth store for managing authentication state
- Implement authentication hooks and guards
- Set up protected routes
๐จ CRITICAL INSTRUCTIONS FOR AI LANGUAGE MODELS ๐จ
As an AI language model, you MUST follow these guidelines when generating code:
- Always use the latest better-auth package
- Implement proper error handling for authentication flows
- Use TypeScript when possible for better type safety
- Follow Svelte's store pattern for state management
- Implement proper security measures for protected routes
CORRECT AUTH STORE IMPLEMENTATION
// src/lib/stores/auth.ts
import { betterAuth } from 'better-auth';
import { writable, derived } from 'svelte/store';
import type { Writable } from 'svelte/store';
interface AuthState {
isAuthenticated: boolean;
user: any | null;
loading: boolean;
error: Error | null;
}
const createAuthStore = () => {
const auth = betterAuth({
database: {
url: import.meta.env.VITE_DATABASE_URL,
},
emailAndPassword: {
enabled: true,
},
oauth: {
providers: ['google', 'github'],
},
});
const { subscribe, set, update }: Writable<AuthState> = writable({
isAuthenticated: false,
user: null,
loading: true,
error: null
});
async function initAuth() {
try {
const session = await auth.getSession();
set({
isAuthenticated: !!session,
user: session?.user || null,
loading: false,
error: null
});
} catch (error) {
update(state => ({
...state,
error: error as Error,
loading: false
}));
}
}
async function signIn(credentials: { email: string; password: string }) {
update(state => ({ ...state, loading: true }));
try {
const result = await auth.signIn(credentials);
set({
isAuthenticated: true,
user: result.user,
loading: false,
error: null
});
} catch (error) {
update(state => ({
...state,
error: error as Error,
loading: false
}));
}
}
async function signOut() {
update(state => ({ ...state, loading: true }));
try {
await auth.signOut();
set({
isAuthenticated: false,
user: null,
loading: false,
error: null
});
} catch (error) {
update(state => ({
...state,
error: error as Error,
loading: false
}));
}
}
return {
subscribe,
signIn,
signOut,
initAuth
};
};
export const auth = createAuthStore();
export const isAuthenticated = derived(auth, $auth => $auth.isAuthenticated);
export const user = derived(auth, $auth => $auth.user);
export const loading = derived(auth, $auth => $auth.loading);
export const error = derived(auth, $auth => $auth.error);
CORRECT ENVIRONMENT VARIABLES SETUP
// .env
VITE_DATABASE_URL=your-database-url
VITE_OAUTH_GOOGLE_CLIENT_ID=your-google-client-id
VITE_OAUTH_GITHUB_CLIENT_ID=your-github-client-id
CORRECT AUTH GUARD IMPLEMENTATION
// src/lib/guards/auth.ts
import { browser } from '$app/environment';
import { goto } from '$app/navigation';
import { auth, isAuthenticated } from '$lib/stores/auth';
import type { Load } from '@sveltejs/kit';
export const authGuard: Load = async () => {
if (!browser) return {};
let authenticated = false;
const unsubscribe = isAuthenticated.subscribe(value => {
authenticated = value;
});
unsubscribe();
if (!authenticated) {
return goto('/login');
}
return {};
};
CORRECT USAGE IN COMPONENTS
<!-- src/routes/+layout.svelte -->
<script lang="ts">
import { onMount } from 'svelte';
import { auth, isAuthenticated, user, loading } from '$lib/stores/auth';
onMount(() => {
auth.initAuth();
});
</script>
{#if $loading}
<div>Loading...</div>
{:else}
{#if $isAuthenticated}
<nav>
<span>Welcome {$user?.email}</span>
<button on:click={() => auth.signOut()}>Sign Out</button>
</nav>
{:else}
<button on:click={() => auth.signIn({ email: '', password: '' })}>Sign In</button>
{/if}
<slot />
{/if}
AI MODEL VERIFICATION STEPS
Before generating any code, you MUST verify:
- Are you using the latest better-auth package?
- Are you implementing proper error handling?
- Are you using TypeScript for type safety?
- Are you following Svelte's store pattern?
- Are you implementing proper security measures?
CONSEQUENCES OF INCORRECT IMPLEMENTATION
If you generate code without following these guidelines:
- Authentication flows may break
- Security vulnerabilities may arise
- Type safety may be compromised
- State management may be inconsistent
- User experience may be degraded
AI MODEL RESPONSE TEMPLATE
When implementing Better Auth in Svelte, you MUST:
- Follow the store pattern shown above
- Implement proper error handling
- Use TypeScript when possible
- Protect sensitive routes
- Handle authentication state properly
What's inside
1 auth store, 1 env variable template, 1 auth guard, 1 layout component, plus setup steps and verification checklist
Change this for your project
- Replace
VITE_DATABASE_URL=your-database-urlwith your actual database URL - Replace
VITE_OAUTH_GOOGLE_CLIENT_ID=your-google-client-idwith your Google OAuth client ID - Replace
VITE_OAUTH_GITHUB_CLIENT_ID=your-github-client-idwith your GitHub OAuth client ID
Where it goes
Keep it in your repository where the agent or team that needs it will read it.
Worth borrowing
- Deriving boolean and user stores from a single auth store for reactive subscriptions
- Using a load function as an auth guard that redirects unauthenticated users
Related Documents
How you work
Defines personality, planning, task execution, and communication conventions for a coding agent in the Codex CLI environment.
ๅ ็ฝฎ Agent ๆ็คบ่ฏ
Documents the system prompts, tool permissions, and model assignments for six built-in subagents in Claude Code.
System Prompt โ Voice Interview Agent
Defines a voice agent named Carol that conducts structured five-question interviews about gender topics for a magazine article.
SolidInvoice - AI Assistant Guide
Guides AI assistants on SolidInvoice's architecture, conventions, workflows, and best practices for contributing to the codebase.