Skip to content

Quick Start

This guide walks you through the full WELD setup from scratch.

The AppRouter type is the bridge between your backend and frontend. Define it once and pass it to Weld<AppRouter>.

types/api.ts
type AppRouter = {
'v1/products': {
GET: {
response: { id: string; name: string; price: number }[]
}
POST: {
body: { name: string; price: number }
response: { id: string }
}
}
}

Zod schemas validate the actual response at runtime.

schemas/product.ts
import { z } from 'zod'
export const ProductSchema = z.object({
id: z.string(),
name: z.string(),
price: z.number().positive(),
})
export const ProductArraySchema = z.array(ProductSchema)
lib/api.ts
import { Weld } from 'weld-http'
import type { AppRouter } from '../types/api'
export const api = new Weld<AppRouter>('https://api.example.com', {
headers: { Authorization: 'Bearer your-token' },
timeout: 10_000,
retry: { attempts: 3, delay: 300 },
})
import { api } from '../lib/api'
import { ProductArraySchema } from '../schemas/product'
const { signal, promise } = api.get('v1/products', ProductArraySchema)
// Via async/await
const products = await promise
// Via reactive signal
signal.status.subscribe((status) => console.log('Status:', status))
signal.data.subscribe((data) => console.log('Data:', data))
import { useWeld } from 'weld-http/react'
import { api } from '../lib/api'
import { ProductArraySchema } from '../schemas/product'
export function ProductList() {
const { data, loading, error } = useWeld(
api.get('v1/products', ProductArraySchema)
)
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error.message}</p>
return (
<ul>
{data?.map((product) => (
<li key={product.id}>
{product.name} — ${product.price}
</li>
))}
</ul>
)
}