Introduction
SolidJS stands out with its fine-grained reactivity that avoids unnecessary re-renders. In 2026, advanced developers leverage its primitives to manage complex states, optimized fetches, and ultra-performant components. This tutorial guides you through creating reactive stores, asynchronous resources, and custom primitives. You will learn to combine batching, context, and SSR for scalable applications. Each concept is illustrated with production-ready code that you can copy directly.
Prerequisites
- Node.js 20+
- Strong knowledge of JavaScript/TypeScript
- Experience with reactivity (signals, effects)
- Vite installed globally
- SolidJS 1.9+
Initializing the SolidJS Project
npm create solid@latest my-advanced-app -- --template ts
cd my-advanced-app
npm installThis command generates a production-ready SolidJS TypeScript project. The template already includes Vite and build tools optimized for fine-grained reactivity.
Creating an Advanced Reactive Store
import { createStore } from 'solid-js/store';
export const [userStore, setUserStore] = createStore({
users: [] as Array<{ id: number; name: string; active: boolean }>,
selectedId: null as number | null,
});
export const addUser = (name: string) => {
setUserStore('users', (users) => [...users, { id: Date.now(), name, active: true }]);
};
export const toggleUser = (id: number) => {
setUserStore('users', (u) => u.id === id, 'active', (active) => !active);
};The store uses createStore for controlled mutability and optimal granularity. Updates are precise and only trigger the necessary re-renders.
Custom Primitive for Batching
import { batch, createEffect, Accessor } from 'solid-js';
export function useBatchedEffect<T>(source: Accessor<T>, fn: (value: T) => void) {
createEffect(() => {
const value = source();
batch(() => {
fn(value);
});
});
}This primitive wraps batch to group updates and avoid intermediate recalculations. Ideal for multiple operations on stores.
Managing Asynchronous Resources
import { createResource, For } from 'solid-js';
import { addUser } from '../stores/userStore';
const fetchUsers = async () => {
const res = await fetch('/api/users');
return res.json();
};
export default function UserList() {
const [users] = createResource(fetchUsers);
return (
<div>
<button onClick={() => addUser('Nouveau')}>Ajouter</button>
<For each={users()}>{(user) => <div>{user.name}</div>}</For>
</div>
);
}createResource automatically handles loading/error states and suspense. The For component ensures ultra-efficient rendering of dynamic lists.
Integration with SolidStart SSR
import { createRouteData } from 'solid-start';
import UserList from '~/components/UserList';
export function routeData() {
return createRouteData(async () => {
const res = await fetch('https://api.example.com/users');
return res.json();
});
}
export default function Home() {
return <UserList />;
}SolidStart enables hydrated SSR with preloaded data. createRouteData ensures flash-free hydration and optimal server-side performance.
Best Practices
- Always use batch for grouped updates
- Prefer custom primitives for reusability
- Avoid effects inside render loops
- Test performance with Solid DevTools
- Structure your stores by business domain
Common Mistakes to Avoid
- Forgetting to use Accessors in primitives
- Modifying state directly without setStore
- Ignoring error handling in createResource
- Using effects for derived calculations (prefer createMemo)
Going Further
Deepen your skills with our advanced SolidJS courses. Also check the official documentation and GitHub examples for 2026 patterns.