This template demonstrates how to integrate Elysia (a Bun-based backend framework) with SvelteKit. It includes authentication, database integration, and API route handling.
Check out the live demo at: https://elysiajs-sveltekit-auth.pattapongj.com/
Test login:
Or you can just register your account.
Test protected page should show access denied when not login https://elysiajs-sveltekit-auth.pattapongj.com/profile
Swagger API for demo: https://elysiajs-sveltekit-auth.pattapongj.com/api/swagger
First, create a SvelteKit project and add necessary dependencies:
# Create new SvelteKit project
npm create svelte@latest my-app
cd my-app
# Install dependencies
bun add elysia @elysiajs/swagger @elysiajs/jwt @elysiajs/eden
bun add @node-rs/argon2 @oslojs/encoding
bun add drizzle-orm postgres
bun add -d drizzle-kit @types/pg
Create the API route handler at src/routes/api/[...slugs]/+server.ts
:
import { Elysia } from 'elysia';
import { swagger } from '@elysiajs/swagger';
const app = new Elysia({ prefix: '/api' })
.use(swagger())
.get('/hi', () => 'Hi Elysia');
export type App = typeof app;
// Handle both GET and POST requests
export const GET = ({ request }) => app.handle(request);
export const POST = ({ request }) => app.handle(request);
Set up PostgreSQL with Docker and create schema:
# Docker compose for PostgreSQL
docker compose up -d
# Run database migrations
bun run db:push
Implement authentication in src/lib/server/auth.ts
:
import { Elysia, t } from 'elysia';
import { jwt } from '@elysiajs/jwt';
export const authRouter = new Elysia({ prefix: '/auth' })
.use(jwt({
secret: process.env.JWT_SECRET
}))
.post('/login', async ({ body, jwt }) => {
// Login logic
})
.post('/register', async ({ body, jwt }) => {
// Registration logic
});
Create a type-safe API client in src/lib/api/client.ts
:
import { treaty } from '@elysiajs/eden';
import type { App } from '@/routes/api/[...slugs]/+server';
export const api = treaty<App>(import.meta.env.PUBLIC_API_URL);
Create .env
file with necessary variables:
DATABASE_URL="postgres://root:mysecretpassword@localhost:5432/svelte_elysia_auth"
PUBLIC_API_URL=http://localhost:5173
PUBLIC_API_PATH=/api
JWT_SECRET=your-secret-key-that-is-at-least-32-characters
PUBLIC_TURNSTILE_SITE_KEY=your_site_key_here
PRIVATE_TURNSTILE_SECRET_KEY=your_secret_key_here
Start the database:
bun run db:start
Run migrations:
bun run db:push
Start development server:
bun run dev
Once running, access the Swagger documentation at:
Note: Due to a known issue in @elysiajs/swagger v1.2.0, the Swagger UI may attempt to call incorrect URLs. A workaround has been implemented in
hooks.server.ts
to redirect/swagger/json
to/api/swagger/json
. If you experience any issues with Swagger documentation, ensure this hook is properly configured:
// src/hooks.server.ts
import { handle } from '@sveltejs/kit';
export const handle = async ({ event, resolve }) => {
if (event.url.pathname === '/swagger/json') {
return Response.redirect('/api/swagger/json', 301);
}
return resolve(event);
};
/api/auth/register
- Register new user/api/auth/login
- Login user/api/auth/me
- Get current user infoThe project utilizes full type safety between frontend and backend through:
For production deployment:
Build the application:
bun run build
Start the production server:
bun run preview