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:
- Compare with [React 18](/en/blog/react-18-deep-dive/
- Learn [Svelte 5](/en/blog/svelte-5-complete-guide/
- Build with [Vue 3](/en/blog/vue-complete-guide/
Resources:
자주 묻는 질문 (FAQ)
Q. 이 내용을 실무에서 언제 쓰나요?
A. Complete Solid.js guide for building ultra-fast web apps. Learn fine-grained reactivity, signals, components, and perfor… 실무에서는 위 본문의 예제와 선택 가이드를 참고해 적용하면 됩니다.
Q. 선행으로 읽으면 좋은 글은?
A. 각 글 하단의 이전 글 또는 관련 글 링크를 따라가면 순서대로 배울 수 있습니다. C++ 시리즈 목차에서 전체 흐름을 확인할 수 있습니다.
Q. 더 깊이 공부하려면?
A. cppreference와 해당 라이브러리 공식 문서를 참고하세요. 글 말미의 참고 자료 링크도 활용하면 좋습니다.
같이 보면 좋은 글 (내부 링크)
이 주제와 연결되는 다른 글입니다.
- [Alpine.js Complete Guide | Lightweight JavaScript Framework](/en/blog/alpine-js-complete-guide/
- [React useMemo and useCallback: When to Use](/en/blog/react-usememo-usecallback-when-to-use/
- [Jotai Complete Guide](/en/blog/jotai-complete-guide/
이 글에서 다루는 키워드 (관련 검색어)
Solid.js, JavaScript, Framework, Reactivity, Performance, Frontend, JSX 등으로 검색하시면 이 글이 도움이 됩니다.