ai gateway models

Every model on Vercel AI Gateway, served by SvelteKit 3 remote functions and async Svelte.

407 models

remote functions 1/6

The server half

models.remote.ts never ships to the browser. Each export is a query(): import it into a component, call it like a function, and SvelteKit turns the call into a typed fetch. Here it reads the public AI Gateway catalog and memoizes it for 5 minutes.

// models.remote.ts (server only)export const getProviders = query(async () => {  const models = await catalog(); // memoized fetch  …});
await in markup · SSR 3/6

Awaited right in the template

No load function, no loading state. During SSR the server waits for the query, renders the options and embeds the result in the HTML, so hydration reuses it instead of fetching again.

<select>  {#each await getProviders() as p (p.id)}    <option value={p.id}>{p.id} · {p.count}</option>  {/each}</select>
$effect.pending() 4/6

Old rows stay until new ones land

Queries are cached per argument, so first and the list share one request. When arguments change, Svelte keeps the current UI on screen until the new data is ready, instead of flashing a spinner. The red bar sweeping across the list, driven by $effect.pending(), is the only loading state.

{@const first = await getModels({ q, provider, page: 0 })} {first.total} models<ol class:loading={$effect.pending()}>…</ol>
one query per page 5/6

Show more = one more await

Each page is its own query. A click renders one more await, which becomes a single GET /_app/remote/…/getModels for just those 20 rows. Earlier pages are already cached.

{#each { length: pages }, i}  {@const { models } = await getModels({ q, provider, page: i })}  {#each models as m}…{/each}{/each} <button onclick={() => pages++}>show more</button>
error() · <svelte:boundary> 6/6

Details from the URL

?model= drives getModel(id), so any panel is a link. An unknown id throws error(404) on the server; the nearest <svelte:boundary> catches it and renders its failed snippet, with a retry button.

{@const m = await getModel(selected)} // models.remote.tsreturn model ?? error(404, `No model called ${id}`);