E2E Type Safety
E2E Type Safety is WELD’s most powerful feature. It means your backend contract flows directly into every request — wrong paths, wrong bodies, and wrong query params break at compile time, not at runtime in production.
Bundle cost: 0KB — all types are erased at compile time.
How it works
Section titled “How it works”You define (or import from your backend) an AppRouter type that describes every route:
type AppRouter = { 'v1/products': { GET: { query?: { page?: number; limit?: number } response: Product[] } POST: { body: { name: string; price: number } response: { id: string } } } 'v1/users/:id': { GET: { params: { id: string } response: User } DELETE: { response: null } }}
const api = new Weld<AppRouter>('https://api.example.com')Now TypeScript knows everything about your API:
// ✅ Correct — TypeScript is happyapi.get('v1/products')api.post('v1/products', Schema, { body: { name: 'Widget', price: 9.99 } })
// ❌ Wrong path — compile errorapi.get('v1/product') // Argument of type '"v1/product"' is not assignable...
// ❌ Wrong body shape — compile errorapi.post('v1/products', Schema, { body: { title: 'Widget' } }) // missing 'name', 'price'Sharing the contract from your backend
Section titled “Sharing the contract from your backend”If your backend is TypeScript, you can export the router type and import it directly:
// backend/src/router.ts (your backend)export type AppRouter = { ... }
import type { AppRouter } from '../../backend/src/router'import { Weld } from 'weld-http'
export const api = new Weld<AppRouter>('https://api.example.com')Now if the backend changes a route, the frontend fails to compile immediately. The contract is enforced automatically.
Type inference helpers
Section titled “Type inference helpers”WELD exports utility types for extracting parts of the contract:
import type { InferResponse, InferBody, InferQuery } from 'weld-http'
// Extract the response type of a routetype Products = InferResponse<AppRouter, 'v1/products', 'GET'>// → Product[]
// Extract the body type of a mutationtype CreateProduct = InferBody<AppRouter, 'v1/products', 'POST'>// → { name: string; price: number }