Recipe

SolidStart Primer

SolidStart is the meta-framework for SolidJS, built on fine-grained reactivity and Vinxi. This primer walks through setting up a Meridian-powered chat route in a SolidStart app, with streaming responses and a typed inference client. Expect zero virtual DOM, signals instead of hooks, and server functions that feel like calling local code.

1. Scaffold the app

Spin up a fresh SolidStart project with the official starter. Pick the “with TailwindCSS” template so the brand tokens drop in without extra config. Install the Meridian SDK alongside.

npm create solid@latest meridian-solid
cd meridian-solid
npm install @meridian/sdk
echo "MERIDIAN_API_KEY=sk_live_..." >> .env

2. Wire a server action

Server functions in SolidStart run only on the server — perfect for keeping your Meridian key out of the client bundle. Stream tokens back via an async generator and consume them in your route with createResource.

// src/lib/chat.ts
'use server';
import { Meridian } from '@meridian/sdk';

const client = new Meridian({ apiKey: process.env.MERIDIAN_API_KEY });

export async function ask(prompt: string) {
  const res = await client.chat.completions.create({
    model: 'azure/model-router',
    messages: [{ role: 'user', content: prompt }],
  });
  return res.choices[0].message.content;
}

3. Render the route

SolidStart routes are just files under src/routes. Drop a form, bind the server action, and you have a working chat surface. Because Solid uses signals, only the response node re-renders — no diffing, no reconciliation.

// src/routes/index.tsx
import { createSignal } from 'solid-js';
import { ask } from '~/lib/chat';

export default function Home() {
  const [reply, setReply] = createSignal('');
  return (
    <form action={async (fd) => setReply(await ask(fd.get('q') as string))}>
      <input name="q" />
      <button>Send</button>
      <p>{reply()}</p>
    </form>
  );
}