Solid.js

Solid.js is a JavaScript UI library with React-like JSX and a fundamentally different engine underneath: fine-grained reactivity with no virtual DOM. Instead of re-running a component and diffing a virtual tree when state changes, Solid tracks exactly which pieces of the DOM depend on which pieces of state, and updates only those — surgically, directly.

The result is React's ergonomics (JSX, components, familiar patterns) with performance at or near the top of every framework benchmark, and a smaller runtime. Solid's signals also proved influential beyond itself: the "signals" primitive it popularized has since been adopted by Angular, Preact, Svelte 5, Vue's reactivity core, and is on the path to a TC39 standard.

TL;DR

Quick Example

A counter and a derived value — note where the reactivity lives:

The critical detail: count is a function (count()), not a value. That function is the subscription — calling it inside JSX tells Solid "this exact text node depends on this signal." When setCount runs, only that text node updates. The component function never runs again.

Core Concepts

Signals: The Whole Model

A signal is a reactive atom — a getter (which subscribes whoever calls it) and a setter (which notifies subscribers):

Three primitives compose everything:

No dependency arrays exist because Solid tracks dependencies automatically — it knows what a computation read because reading is a function call it observed. The entire class of React "stale closure / missing dependency" bugs simply doesn't occur.

Components Run Once — The Big Shift

This is where React developers stumble. In React, the component function is the render, called on every state change. In Solid, the component function is setup that runs exactly once; reactivity happens beneath it. Consequences:

Because components don't re-run, there's no need for useCallback, useMemo-for-referential-stability, React.memo, or the whole apparatus of preventing re-renders. There are no re-renders to prevent.

Control Flow Components

Since you can't just re-run JSX with a new .map(), Solid provides reactive control-flow components that update efficiently:

<For> reconciles by reference and moves DOM nodes rather than recreating them — the fine-grained equivalent of a keyed list, without a diff pass.

Stores and SolidStart

For nested/complex state, createStore provides a reactive proxy with fine-grained updates deep into objects (setStore("user", "profile", "name", "Bob") updates only that leaf's subscribers). SolidStart is the meta-framework — file-based routing, SSR/streaming, server functions ("use server"), built on Vite — playing the role Next.js plays for React.

Solid vs React vs Svelte

Solid's positioning: "React's JSX, Svelte's performance, no virtual DOM." You keep JSX and React-shaped mental models but pay none of the re-render tax. Versus Svelte, it's a library (JSX, standard tooling) rather than a compiler with custom syntax. The universal caveat is ecosystem depth — React's library/hiring/answer gravity is unmatched, so Solid is often chosen by teams who value the performance and DX enough to accept building a bit more themselves. The vindication is signals spreading everywhere: Solid's core idea won even where Solid didn't.

Common Mistakes

Destructuring Props

Props are a reactive proxy; destructuring reads them once at setup and freezes them. Use props.x, or splitProps/mergeProps helpers.

Reading Signals Outside Tracking Scopes

Reading count() in the component body (not in JSX, an effect, or a memo) reads it once with no subscription — a common "why doesn't it update?" A value that must react must be read inside a reactive context.

Applying React Optimization Habits

useCallback/useMemo-style wrapping is pointless and confusing in Solid — there are no re-renders to optimize. Bringing React's performance folklore over adds noise without benefit.

Forgetting Signals Are Getters

count is the getter function; count() is its value. Passing count (the function) where a value is expected, or logging count and seeing [Function], is the classic first-day trip.

FAQ

Is Solid production-ready?

Yes — it's stable (1.0 in 2022), used in production, and SolidStart provides the full-stack story. The maturity question is ecosystem breadth (fewer prebuilt component libraries, integrations, and tutorials than React), not core reliability.

How hard is the switch from React?

The syntax transfers almost completely (JSX, props, composition), so you're productive in hours — but the "components run once" model requires genuinely re-wiring your instincts. Developers describe an initial "wait, why doesn't this re-run?" period, then relief at losing dependency arrays and memoization.

What are "signals" and why is everyone adopting them?

A signal is a reactive value that automatically tracks its readers and notifies them on change — fine-grained reactivity's atom. Solid popularized the primitive; Angular, Preact, Svelte 5, Vue, and a TC39 proposal have since embraced it. Learning Solid is partly learning the model the whole ecosystem is converging on.

Solid or Svelte?

Both deliver top performance without a virtual DOM. Solid keeps standard JSX and tooling (a library); Svelte uses a compiler with its own file format and arguably the gentler syntax. Choose Solid if you want to stay in JSX/standard-JS land; Svelte if you prefer its authoring experience.

Does Solid do SSR and streaming?

Yes — SolidStart supports SSR, streaming, progressive hydration, and server functions, and fine-grained reactivity makes hydration unusually efficient (it can hydrate exactly what's interactive). It's a legitimate Next.js alternative for teams on Solid.

Related Topics

References