Why SolidStart?
SolidStart is the meta-framework for SolidJS - the UI library with fine-grained reactivity that skips the virtual DOM entirely. If you want React-like DX with significantly better runtime performance, SolidStart gives you SSR, routing, and server functions out of the box.
Quick Start
npm init solid@latest my-app
cd my-app
npm install
npm run dev
Server Functions (RPC)
// src/lib/api.ts
'use server';
import { db } from './db';
export async function getPosts(query?: string) {
return db.posts.findMany({
where: query ? { title: { contains: query } } : undefined,
orderBy: { createdAt: 'desc' },
take: 20,
});
}
export async function createPost(title: string, body: string) {
if (!title || !body) throw new Error('Title and body required');
return db.posts.create({ data: { title, body } });
}
export async function deletePost(id: string) {
return db.posts.delete({ where: { id } });
}
Routes with Data Loading
// src/routes/posts/index.tsx
import { createAsync, useSearchParams } from '@solidjs/router';
import { For, Suspense } from 'solid-js';
import { getPosts } from '~/lib/api';
export default function PostsPage() {
const [params] = useSearchParams();
const posts = createAsync(() => getPosts(params.q));
return (
<div>
<h1>Posts</h1>
<form method="get">
<input name="q" value={params.q || ''} placeholder="Search..." />
</form>
<Suspense fallback={<p>Loading...</p>}>
<ul>
<For each={posts()}>
{(post) => (
<li>
<a href={`/posts/${post.id}`}>{post.title}</a>
</li>
)}
</For>
</ul>
</Suspense>
</div>
);
}
Fine-Grained Reactivity
import { createSignal, createMemo, createEffect } from 'solid-js';
export default function Counter() {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
createEffect(() => {
console.log('Count changed:', count());
});
return (
<div>
<p>Count: {count()}</p>
<p>Doubled: {doubled()}</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
</div>
);
}
API Routes
// src/routes/api/posts.ts
import { json } from '@solidjs/router';
import type { APIEvent } from '@solidjs/start/server';
import { db } from '~/lib/db';
export async function GET(event: APIEvent) {
const posts = await db.posts.findMany({ take: 50 });
return json(posts);
}
export async function POST(event: APIEvent) {
const body = await event.request.json();
const post = await db.posts.create({ data: body });
return json(post, { status: 201 });
}
Middleware
// src/middleware.ts
import { createMiddleware } from '@solidjs/start/middleware';
export default createMiddleware({
onRequest: [
(event) => {
const start = Date.now();
event.locals.startTime = start;
},
],
onBeforeResponse: [
(event) => {
const duration = Date.now() - event.locals.startTime;
console.log(`${event.request.method} ${event.request.url} - ${duration}ms`);
},
],
});
Real-World Use Case
A fintech startup needed a dashboard that updates hundreds of data points in real-time. React re-rendered entire component trees on each WebSocket message. SolidStart with fine-grained reactivity only updates the exact DOM nodes that changed. Result: 60fps even with 500+ live-updating cells, and bundle size dropped 40%.
Building reactive apps? I create custom data pipelines and automation tools. Check out my web scraping toolkit on Apify or reach me at spinov001@gmail.com for custom solutions.
Top comments (0)