π‘οΈ Type Safety First
End-to-end type safety from database to UI with automatic type generation for routes and APIs.
Full-stack, type-safe web framework built on Vite, Nitro, and Svelte 5.
Create a full-stack application with just a few files:
<!-- src/app/index.svelte -->
<script lang="ts">
import { rpc } from '$oxide'
const posts = await rpc.api.posts.list()
</script>
<h1>Latest Posts</h1>
{#each posts as post}
<article>{post.title}</article>
{/each}// src/app/api/posts.ts
import { base } from "$lib/orpc";
export const router = {
list: base.handler(async ({ context }) => {
return await context.db.posts.findMany();
}),
};Organize your app with intuitive file structure:
src/app/
βββ index.svelte β /
βββ about.svelte β /about
βββ users/
β βββ [id].svelte β /users/:id
β βββ [id]/
β βββ settings.svelte β /users/:id/settings
βββ api/
βββ users.ts β /api/users/*
βββ posts.ts β /api/posts/*Build APIs with full type safety and automatic client generation:
// Define once
export const router = {
getUser: base
.input(z.object({ id: z.string() }))
.handler(async ({ input, context }) => {
return await context.db.users.findUnique({ where: { id: input.id } });
}),
};
// Use everywhere with full types
const user = await rpc.api.users.getUser({ id: "123" });Leverage the latest Svelte features with runes and enhanced reactivity:
<script lang="ts">
import { useRoute, rpc } from '$oxide'
const route = useRoute()
let posts = $state([])
$effect(() => {
const query = route.query.get('q') || ''
rpc.api.posts.search({ query }).then(results => {
posts = results
})
})
</script>Ready to build your next application? Get started with Oxide in minutes.