# SolidJS: Fine-Grained Reactivity Guide and SolidJS vs React

SolidJS is a reactive JavaScript UI library with no virtual DOM, built on signals and compiled JSX. This guide explains how it works, shows the core primitives with code, compares it with React, Vue and Svelte, and covers SolidStart and the Solid 2.0 release candidates.

Tags: javascript, frameworks, web-development
Published: 2023-04-15 (updated 2026-10-22)


SolidJS (also written Solid.js) is a reactive JavaScript library for building user interfaces, created by Ryan Carniato. It looks like React because it uses JSX, but it works very differently underneath: there is no virtual DOM, and updates happen through fine-grained reactivity built on signals.

## What Is SolidJS?

SolidJS is a declarative UI library that compiles JSX into direct DOM operations and tracks state with signals. Components run once to set up the DOM, and when a signal changes, only the exact text nodes or attributes that depend on it update. There is no virtual DOM diffing and no component re-rendering, which gives SolidJS very high benchmark performance and a small runtime.

## How SolidJS Works

### Signals

State in Solid lives in signals. `createSignal` returns a getter and a setter:

```jsx
import { createSignal } from 'solid-js';

function Counter() {
  const [count, setCount] = createSignal(0);

  return (
    <button onClick={() => setCount(count() + 1)}>
      Count: {count()}
    </button>
  );
}
```

Notice that you call `count()` to read the value. That call is how Solid knows which parts of the UI depend on the signal.

### Components run once

In React, a component function re-runs on every state change. In Solid, the function body runs once. Only the expressions that read signals (like `{count()}` above) are re-evaluated. That is why Solid has no `useMemo`, `useCallback` or dependency arrays.

### Effects and derived values

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

const [first, setFirst] = createSignal('Ada');
const [last, setLast] = createSignal('Lovelace');

const fullName = createMemo(() => `${first()} ${last()}`);

createEffect(() => {
  console.log('Name is now', fullName());
});
```

`createMemo` caches a derived value, and `createEffect` re-runs when the signals it reads change. Dependencies are tracked automatically.

### Control flow components

Because components run once, Solid uses components for conditionals and lists instead of plain JavaScript expressions:

```jsx
import { Show, For } from 'solid-js';

function TodoList(props) {
  return (
    <Show when={props.todos.length} fallback={<p>Nothing to do</p>}>
      <ul>
        <For each={props.todos}>{(todo) => <li>{todo.title}</li>}</For>
      </ul>
    </Show>
  );
}
```

## SolidJS vs React

Solid and React share JSX and a component mindset, but their runtimes differ.

| | SolidJS | React |
|---|---|---|
| Rendering | No virtual DOM, direct DOM updates | Virtual DOM diffing |
| Component function | Runs once | Re-runs on every state change |
| State | Signals (`createSignal`) | Hooks (`useState`) |
| Memoization | Not needed, tracking is automatic | `useMemo`, `useCallback`, or the React Compiler |
| Props | Reactive, do not destructure | Plain values, destructure freely |
| Ecosystem | Small but growing | Huge |
| Meta-framework | SolidStart | Next.js, Remix, TanStack Start |
| Hiring | Niche | Dominant |

**When to choose SolidJS:** performance-sensitive UIs with frequent updates, small bundles, and teams that like React syntax but want fewer footguns around re-renders. **When to stay with React:** you need the ecosystem, libraries, hiring pool and framework support, such as Server Components in Next.js. React also now has the [React Compiler](/blog/the-react-compiler-is-here-say-goodbye-to-usememo-and-usecallback/), which closes part of the gap by automating memoization.

The biggest habit change coming from React: do not destructure props, because that reads the values once and breaks reactivity. Use `props.name`, or Solid's `splitProps` helper.

## SolidJS vs Vue and Svelte

Vue also has a fine-grained reactivity system, but it still renders through a virtual DOM (see my [Vue 3 guide](/blog/a-comprehensive-introduction-to-vuejs/)). Svelte compiles components away like Solid does, and Svelte 5 moved to a signals-based model called runes, which I compare with React in [Svelte 5 vs React](/blog/svelte-5-vs-react-2026/). All three converge on the same idea: track exactly what depends on what, and update only that.

## SolidStart and Solid 2.0

SolidStart is the official meta-framework for Solid, covering routing, server rendering and server functions. For the meta-framework landscape on the React side, see [TanStack Start vs Next.js](/blog/tanstack-start-vs-nextjs-2026/).

As of this writing, Solid 2.0 is in release-candidate stage on GitHub (2.0.0-rc.17), so Solid 1.x remains the stable line. Check the Solid releases page and migration notes before upgrading, since 2.0 includes changes to the core primitives.

## Frequently Asked

**Is SolidJS better than React?** It is faster in benchmarks and avoids re-render pitfalls, but React has a far larger ecosystem and job market. Pick Solid for performance and simplicity, React for ecosystem and hiring.

**Does SolidJS use a virtual DOM?** No. It compiles JSX to direct DOM operations and updates only what changed through signals.

**Is SolidJS hard to learn if I know React?** The syntax is familiar. The main adjustments are calling signals as functions, not destructuring props, and remembering that components run once.

**What is SolidStart?** The official full-stack meta-framework for SolidJS, with routing, server rendering and server functions.

**Is Solid 2.0 released?** As of this writing it is in release-candidate stage, so the stable line is still 1.x.
