DEV Community

Alex Spinov
Alex Spinov

Posted on

SolidStart Has a Free API — Full-Stack SolidJS with Fine-Grained Reactivity

SolidStart is the meta-framework for SolidJS — file-based routing, SSR, API routes, and server functions. SolidJS's fine-grained reactivity means no re-renders, ever.

Why SolidStart?

  • Zero re-renders — SolidJS updates only what changed, no diffing
  • Server functions — call backend from components with 'use server'
  • File-based routingroutes/about.tsx = /about
  • Islands — partial hydration for ultra-fast page loads

Quick Start

npm init solid@latest myapp
cd myapp
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Basic Page

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

export default function Home() {
  const [count, setCount] = createSignal(0);

  return (
    <main>
      <h1>Home</h1>
      <p>Count: {count()}</p>
      <button onClick={() => setCount(count() + 1)}>Increment</button>
    </main>
  );
}
Enter fullscreen mode Exit fullscreen mode

Data Loading

// src/routes/users.tsx
import { createAsync, cache } from '@solidjs/router';

const getUsers = cache(async () => {
  'use server';
  return await db.select().from(users);
}, 'users');

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

export default function Users() {
  const users = createAsync(() => getUsers());

  return (
    <ul>
      <For each={users()}>
        {(user) => <li>{user.name}</li>}
      </For>
    </ul>
  );
}
Enter fullscreen mode Exit fullscreen mode

Server Functions

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

const createUser = action(async (formData: FormData) => {
  'use server';
  const name = formData.get('name') as string;
  const email = formData.get('email') as string;
  await db.insert(users).values({ name, email });
  throw redirect('/users');
});

export default function NewUser() {
  return (
    <form action={createUser} method="post">
      <input name="name" placeholder="Name" />
      <input name="email" placeholder="Email" />
      <button type="submit">Create</button>
    </form>
  );
}
Enter fullscreen mode Exit fullscreen mode

API Routes

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

export async function GET() {
  const allUsers = await db.select().from(users);
  return json(allUsers);
}

export async function POST({ request }) {
  const body = await request.json();
  const user = await db.insert(users).values(body).returning();
  return json(user, { status: 201 });
}
Enter fullscreen mode Exit fullscreen mode

Reactive Primitives

import { createSignal, createMemo, createEffect } from 'solid-js';

function App() {
  const [firstName, setFirstName] = createSignal('Alice');
  const [lastName, setLastName] = createSignal('Smith');

  // Derived — only recomputes when deps change
  const fullName = createMemo(() => `${firstName()} ${lastName()}`);

  // Side effect — runs when deps change
  createEffect(() => {
    console.log(`Name changed to: ${fullName()}`);
  });

  return <h1>{fullName()}</h1>;
}
Enter fullscreen mode Exit fullscreen mode

Building reactive data dashboards? Check out my Apify actors for real-time web scraping, or email spinov001@gmail.com for custom SolidJS solutions.

SolidStart, Next.js, or SvelteKit — which meta-framework do you pick? Share below!

Top comments (0)