solidjs/solid
Fun facts
A few things you would only notice by spelunking through the source.
The reactive core started life as someone else's library
The MIT license preamble at the top of packages/solid/src/reactive/signal.ts reads:
Inspired by S.js by Adam Haile, https://github.com/adamhaile/S
packages/solid/src/reactive/array.ts carries a similar credit to S-array by the same author. Solid's reactive graph algorithm is a direct intellectual descendant of these two libraries; the Computation, Owner, and observer-tracking layout in signal.ts are recognizably the S.js shape, ported to TypeScript and extended with transitions, resources, and hydration.
Almost the entire codebase is one person
git log --pretty=format:'%an' | sort | uniq -c | sort -nr against main:
| Author | Commits |
|---|---|
| Ryan Carniato | 1,426 |
| Damian Tarnawski | 33 |
| Dan Jutan | 23 |
| Xavier Loh | 22 |
| Joe Pea | 18 |
| dependabot[bot] | 15 |
That is ~76% of all commits. Solid is unusual among modern UI libraries for being so close to a solo project at the source-code level. The community contributions are concentrated in the surrounding ecosystem (solidjs-community/*, solid-docs-next, etc.), which the CONTRIBUTING.md describes as deliberate.
The biggest source file is bigger than most libraries
packages/solid/src/reactive/signal.ts is 1,821 lines. By itself, it is larger than the entire published source of the next-largest module (packages/solid/src/server/rendering.ts at 715 lines) — and it is the one file that, if you understand it, lets you understand most of Solid.
rxcore is a fake import name
If you grep the source for rxcore you will find imports like:
import { setAttribute, ... } from "rxcore";rxcore is not an installed package. The Rollup config (packages/solid/rollup.config.js) and the Vitest config (packages/solid/vite.config.mjs) both rewrite rxcore to packages/solid/web/src/core at build/test time. The same source code can therefore produce a browser bundle (using dom-expressions' DOM core) and a server bundle (using a server-only core that escapes HTML), without conditionals scattered through the source.
Solid has its own scheduler — and it borrowed React's
The block comment at the top of packages/solid/src/reactive/scheduler.ts says it plainly:
// Basic port modification of Reacts Scheduler: https://github.com/facebook/react/tree/master/packages/scheduler
The MessageChannel-based time-slicing and isInputPending integration are direct ports. A recent fix (prevent createDeferred from keeping Node.js process alive, Apr 2025) added a port1.unref() / port2.unref() guard so that the scheduler does not hold the Node event loop open after dispose.
Symbol.observable polyfill that isn't a polyfill
packages/solid/src/reactive/observable.ts declares:
declare global {
interface SymbolConstructor {
readonly observable: symbol;
}
}…but does not assign Symbol.observable. The accompanying comment explains that doing so would conflict with RxJS, so Solid intentionally only declares the type and falls back to the string "@@observable" at runtime. The terse Symbol.observable || "@@observable" lookup at the bottom of the file is deliberately written without an intermediate variable so it minifies cleanly.
Internal symbols all start with $
The runtime uses a small set of well-known symbols as internal markers:
| Symbol | Purpose |
|---|---|
$PROXY |
Identifies a value as a Solid proxy (signals/store) |
$TRACK |
Forces self-tracking when read on a store node |
$RAW |
Returns the underlying object behind a store proxy |
$NODE |
Holds the per-property DataNode map on a store |
$HAS |
Holds the per-property "has-key" reactive map on a store |
$SELF |
Self-key used in store node bookkeeping |
$DEVCOMP |
Tags dev-only component wrappers |
They are all created with Symbol("solid-...") or Symbol("store-..."), so they survive bundling and are unique across realms.
You can use Solid without a compiler
Most users reach for JSX, but packages/solid/h/src/index.ts (the h() factory) and packages/solid/html/src/index.ts (the tagged-template html ` literal) let you write Solid components with no build step at all:
import h from "solid-js/h";
const Counter = () => h("button", { onClick: ... }, count);Both come with caveats — reactive expressions must be wrapped in functions manually because there is no compiler doing the wrapping for you (see the solid-js/h and solid-js/html READMEs).
And you can use Solid for non-DOM targets
packages/solid/universal/src/index.ts re-exports createRenderer from dom-expressions/universal, and babel-preset-solid accepts generate: "universal". This is how community projects render Solid trees to terminals, canvas, native, or anything else with a tree-shaped target.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.