SolidStart is the official meta-framework for SolidJS. It provides server functions, file-based routing, and SSR — with the reactivity model that makes Solid the fastest UI framework.
What Makes SolidStart Special?
- True reactivity — fine-grained updates, no Virtual DOM
- Server functions — RPC-style server calls from client code
- Streaming SSR — progressive HTML streaming
- Vinxi-powered — universal deployment (Node, Vercel, Cloudflare)
- Tiny — Solid's runtime is 7KB gzipped
The Hidden API: Server Functions
// src/routes/products/[id].tsx
import { createAsync, cache } from '@solidjs/router';
// Server function — runs on the server, called from client
const getProduct = cache(async (id: string) => {
'use server';
const product = await db.product.findUnique({ where: { id } });
if (!product) throw new Error('Not found');
return product;
}, 'product');
export const route = { load: ({ params }) => getProduct(params.id) };
export default function ProductPage() {
const params = useParams();
const product = createAsync(() => getProduct(params.id));
return (
<Show when={product()}>
{(p) => (
<div>
<h1>{p().title}</h1>
<p>${p().price}</p>
</div>
)}
</Show>
);
}
Action API — Server Mutations
import { action, redirect } from '@solidjs/router';
const createProduct = action(async (formData: FormData) => {
'use server';
const product = await db.product.create({
data: {
title: formData.get('title') as string,
price: Number(formData.get('price'))
}
});
throw redirect(`/products/${product.id}`);
});
export default function NewProduct() {
return (
<form action={createProduct} method="post">
<input name="title" required />
<input name="price" type="number" required />
<button type="submit">Create</button>
</form>
);
}
Reactivity API — Fine-Grained Updates
import { createSignal, createEffect, For } from 'solid-js';
function TodoApp() {
const [todos, setTodos] = createSignal([]);
const [filter, setFilter] = createSignal('all');
// Only re-runs when filter() changes — not on every todo update
const filtered = () => {
if (filter() === 'all') return todos();
return todos().filter(t =>
filter() === 'done' ? t.completed : !t.completed
);
};
// Fine-grained: only the changed <li> updates, not the whole list
return (
<For each={filtered()}>
{(todo) => <li>{todo.title}</li>}
</For>
);
}
Quick Start
npm init solid@latest my-app -- --with ssr
cd my-app && npm install && npm run dev
Why Teams Choose SolidStart
A developer shared: "We migrated from Next.js to SolidStart. Our Lighthouse performance score went from 72 to 98. The fine-grained reactivity means no unnecessary re-renders — the UI updates exactly what changed, nothing more."
Building fast web apps? Email spinov001@gmail.com or check my tools.
SolidJS vs React — have you tried the reactivity difference?
Top comments (0)