DEV Community

Alex Spinov
Alex Spinov

Posted on

SolidStart Has a Free API — Heres How to Build Reactive Full-Stack Apps

SolidStart is the full-stack framework for SolidJS — giving you server functions, file-based routing, and fine-grained reactivity out of the box.

Why SolidStart?

  • Fine-grained reactivity: No virtual DOM, surgical updates
  • Server functions: Call server code directly from components
  • File-based routing: Automatic route generation
  • SSR/SSG/CSR: Choose rendering strategy per route
  • Vinxi-powered: Modern bundler with HMR

Quick Setup

npm init solid@latest my-app
cd my-app && npm install && npm run dev
Enter fullscreen mode Exit fullscreen mode

File-Based Routing

src/routes/
  index.tsx        -> /
  about.tsx        -> /about
  posts/
    index.tsx      -> /posts
    [id].tsx       -> /posts/:id
Enter fullscreen mode Exit fullscreen mode

Data Loading with createAsync

import { createAsync, cache } from '@solidjs/router';

const getPosts = cache(async () => {
  'use server';
  return await db.post.findMany({ orderBy: { createdAt: 'desc' } });
}, 'posts');

export const route = { load: () => getPosts() };

export default function Posts() {
  const posts = createAsync(() => getPosts());
  return (
    <ul>
      <For each={posts()}>
        {post => <li>{post.title}</li>}
      </For>
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Server Functions

import { action, redirect } from '@solidjs/router';

const createPost = action(async (formData: FormData) => {
  'use server';
  const title = formData.get('title') as string;
  const body = formData.get('body') as string;
  await db.post.create({ data: { title, body } });
  throw redirect('/posts');
});

export default function NewPost() {
  return (
    <form action={createPost} method="post">
      <input name="title" placeholder="Title" />
      <textarea name="body" placeholder="Content" />
      <button type="submit">Create</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

API Routes

// src/routes/api/posts.ts
import { json } from '@solidjs/router';

export async function GET() {
  const posts = await db.post.findMany();
  return json(posts);
}

export async function POST({ request }) {
  const body = await request.json();
  const post = await db.post.create({ data: body });
  return json(post, { status: 201 });
}
Enter fullscreen mode Exit fullscreen mode

Middleware

import { createMiddleware } from '@solidjs/start/middleware';

export default createMiddleware({
  onRequest: [async (event) => {
    const session = await getSession(event);
    if (!session) return new Response('Unauthorized', { status: 401 });
  }],
});
Enter fullscreen mode Exit fullscreen mode

Real-World Use Case

A team built a real-time dashboard with SolidStart. Compared to React, their component re-renders dropped from 847 to 12 per interaction — because SolidJS updates only what changes, not the entire tree.


Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.

Top comments (0)