Solid.js Complete Guide | Fast Reactive JavaScript Framework
이 글의 핵심
Solid.js is a reactive JavaScript framework that compiles to efficient vanilla JavaScript. It uses fine-grained reactivity for exceptional performance without a Virtual DOM.
Introduction
Solid.js is a declarative JavaScript framework for building user interfaces. Unlike React, it compiles to efficient vanilla JavaScript without a Virtual DOM, achieving exceptional performance through fine-grained reactivity.
Created by Ryan Carniato (former React core team member), Solid.js has gained significant traction as the fastest reactive framework in the JavaScript ecosystem.
Why Solid.js Matters
Performance benchmarks (js-framework-benchmark):
- Solid.js is faster than React, Vue, and Svelte in most benchmarks
- 2-3x faster than React for updates and DOM manipulation
- Smaller bundle size: ~7KB gzipped (React is ~40KB)
Real-world adoption:
- Cloudflare uses Solid.js for their dashboard analytics
- Netlify adopted Solid.js for internal tools
- SolidStart (meta-framework) reached 1.0 in 2024
- ~100k weekly npm downloads (growing 50% year-over-year)
Why developers choose Solid.js:
- Performance-critical apps — dashboards, data visualization, real-time apps
- React-like DX — uses JSX, similar patterns, easy migration for React devs
- Smaller bundles — 7KB vs React’s 40KB baseline
- Fine-grained reactivity — only re-executes what actually changed
When to use Solid.js:
- Need maximum performance (60fps animations, large lists)
- Want React-like DX without React overhead
- Building data-heavy dashboards or real-time apps
- Care about bundle size and initial load time
When to use React instead:
- Need the largest ecosystem and community
- Require specific React libraries without Solid alternatives
- Team is already expert in React patterns
- Using React Native for mobile (Solid is web-only)
React vs Solid
React:
function Counter() {
const [count, setCount] = useState(0);
console.log('Component re-renders'); // Logs on every update
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Solid:
function Counter() {
const [count, setCount] = createSignal(0);
console.log('Component runs once'); // Only logs once!
return <button onClick={() => setCount(count() + 1)}>{count()}</button>;
}
1. Installation
# Create new project
npx degit solidjs/templates/ts my-app
cd my-app
npm install
npm run dev
# Or with Vite
npm create vite@latest my-app -- --template solid-ts
2. Reactive Primitives
Signals (State)
import { createSignal } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0);
// Read: count()
// Write: setCount(value)
return (
<div>
<p>Count: {count()}</p>
<button onClick={() => setCount(count() + 1)}>Increment</button>
<button onClick={() => setCount(c => c + 1)}>Increment (updater)</button>
</div>
);
}
Derived Signals (Computed)
import { createSignal, createMemo } from 'solid-js';
function ExpensiveComputation() {
const [count, setCount] = createSignal(0);
// Memoized computation
const doubled = createMemo(() => {
console.log('Computing doubled');
return count() * 2;
});
return (
<div>
<p>Count: {count()}</p>
<p>Doubled: {doubled()}</p>
<button onClick={() => setCount(count() + 1)}>Increment</button>
</div>
);
}
Effects
import { createSignal, createEffect } from 'solid-js';
function Logger() {
const [count, setCount] = createSignal(0);
// Runs when dependencies change
createEffect(() => {
console.log('Count changed to:', count());
});
return <button onClick={() => setCount(count() + 1)}>Click</button>;
}
3. Control Flow
Show Component
import { Show } from 'solid-js';
function UserProfile({ userId }: { userId: number | null }) {
return (
<Show when={userId} fallback={<div>Please log in</div>}>
<UserDetails userId={userId!} />
</Show>
);
}
For Component
import { For } from 'solid-js';
function TodoList() {
const [todos, setTodos] = createSignal([
{ id: 1, text: 'Learn Solid' },
{ id: 2, text: 'Build app' },
]);
return (
<ul>
<For each={todos()}>
{(todo, index) => (
<li>
{index() + 1}. {todo.text}
</li>
)}
</For>
</ul>
);
}
Switch Component
import { Switch, Match } from 'solid-js';
function StatusBadge({ status }: { status: string }) {
return (
<Switch fallback={<span>Unknown</span>}>
<Match when={status === 'active'}>
<span className="badge-green">Active</span>
</Match>
<Match when={status === 'pending'}>
<span className="badge-yellow">Pending</span>
</Match>
<Match when={status === 'inactive'}>
<span className="badge-gray">Inactive</span>
</Match>
</Switch>
);
}
4. Components
Props
import { Component } from 'solid-js';
interface ButtonProps {
onClick: () => void;
children: any;
variant?: 'primary' | 'secondary';
}
const Button: Component<ButtonProps> = (props) => {
return (
<button
onClick={props.onClick}
class={`btn btn-${props.variant || 'primary'}`}
>
{props.children}
</button>
);
};
Children
import { children } from 'solid-js';
function Container(props: { children: any }) {
const c = children(() => props.children);
return <div class="container">{c()}</div>;
}
5. Stores (Global State)
import { createStore } from 'solid-js/store';
function TodoApp() {
const [todos, setTodos] = createStore([
{ id: 1, text: 'Learn Solid', completed: false },
]);
const addTodo = (text: string) => {
setTodos([...todos, { id: Date.now(), text, completed: false }]);
};
const toggleTodo = (id: number) => {
setTodos(
(todo) => todo.id === id,
'completed',
(completed) => !completed
);
};
return (
<div>
<For each={todos}>
{(todo) => (
<div>
<input
type="checkbox"
checked={todo.completed}
onChange={() => toggleTodo(todo.id)}
/>
{todo.text}
</div>
)}
</For>
</div>
);
}
6. Context API
import { createContext, useContext } from 'solid-js';
const UserContext = createContext<{ name: string }>();
function App() {
const [user] = createSignal({ name: 'John' });
return (
<UserContext.Provider value={user()}>
<UserProfile />
</UserContext.Provider>
);
}
function UserProfile() {
const user = useContext(UserContext);
return <div>{user?.name}</div>;
}
7. Async Data
createResource
import { createResource } from 'solid-js';
async function fetchUser(id: number) {
const res = await fetch(`/api/users/${id}`);
return res.json();
}
function UserProfile() {
const [userId, setUserId] = createSignal(1);
const [user] = createResource(userId, fetchUser);
return (
<div>
<Show when={user.loading}>Loading...</Show>
<Show when={user.error}>Error: {user.error.message}</Show>
<Show when={user()}>
<h1>{user()?.name}</h1>
</Show>
</div>
);
}
8. Routing
npm install @solidjs/router
import { Router, Route, A } from '@solidjs/router';
function App() {
return (
<Router>
<nav>
<A href="/">Home</A>
<A href="/about">About</A>
</nav>
<Route path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/users/:id" component={UserProfile} />
</Router>
);
}
9. Performance
Solid.js is incredibly fast:
- No Virtual DOM - direct DOM manipulation
- Fine-grained reactivity - only what changed updates
- Compiled - optimized at build time
Benchmark results (js-framework-benchmark):
- Solid.js: 1.0x (baseline)
- React: 1.5x slower
- Vue: 1.3x slower
Summary
Solid.js delivers exceptional performance:
- Fine-grained reactivity updates only what changed
- No Virtual DOM for faster updates
- Familiar JSX syntax like React
- Compile-time optimization for smaller bundles
- Full TypeScript support
Key Takeaways:
- Components run once, signals track changes
- Use
createSignalfor state,createMemofor derived - Control flow with
<Show>,<For>,<Switch> createStorefor complex nested statecreateResourcefor async data
Next Steps:
Resources:
Frequently Asked Questions (FAQ)
Q. When would I use this in practice?
A. Complete Solid.js guide for building ultra-fast web apps. Learn fine-grained reactivity, signals, components, and perfor…
Q. What should I read before this?
A. Follow the previous article or related articles links at the bottom of each post to learn in sequence.
Q. Where can I study this more deeply?
A. Check cppreference and the relevant library’s official documentation. The reference links at the end of the article are also worth using.
Related Articles (Internal Links)
Other articles related to this topic.
- Alpine.js Complete Guide | Lightweight JavaScript Framework
- React useMemo and useCallback: When to Use
- Jotai Complete Guide
Keywords Covered in This Article (Related Search Terms)
This article covers Solid.js, JavaScript, Framework, Reactivity, Performance, Frontend, JSX.