solidjs/solid
Architecture
Solid is a fine-grained reactive UI library. Three layers cooperate to render a component: a compiler that rewrites JSX, a reactive runtime of signals, memos, and effects, and one or more renderers that turn the reactive graph into real output (DOM, HTML strings, custom backends).
High-level shape
graph LR
JSX[JSX source<br>.tsx / .jsx]
JSX -->|babel-preset-solid| Babel[babel-plugin-<br>jsx-dom-expressions]
Babel -->|generates calls into| Runtime[Reactive runtime<br>packages/solid/src]
Babel -->|generates calls into| Renderer[Renderer module<br>web / server / universal]
Runtime <-->|graph subscriptions| Renderer
Store[solid-js/store<br>proxy-based stores] -->|signals| Runtime
Renderer -->|DOM nodes / HTML / custom| Output[Browser DOM<br>or HTML stream<br>or custom target]babel-preset-solid (packages/babel-preset-solid/index.js) wires up babel-plugin-jsx-dom-expressions with default options: moduleName: "solid-js/web", the standard built-ins (For, Show, Switch, Match, Suspense, SuspenseList, Portal, Index, Dynamic, ErrorBoundary), and generate: "dom". The compiler emits direct calls into whichever module name you point it at — solid-js/web for browsers, solid-js/web (with the server export condition) for SSR, or any custom module for generate: "universal".
Reactive runtime
The runtime lives in packages/solid/src/reactive/:
signal.ts(~1800 lines) is the heart: it defines theOwner,Computation,SignalStategraph and implementscreateSignal,createMemo,createEffect,createRoot,createResource,createContext, transitions, error boundaries, and the update queue.scheduler.tsis a port of React's MessageChannel-based scheduler, used byenableScheduling()to time-slice work across frames.array.tsprovidesmapArrayandindexArray, the keyed/non-keyed list reconcilers consumed by<For>and<Index>.observable.tsprovides interop with TC39 Observables / RxJS viaobservable()andfrom().
graph TD
Signal[SignalState<br>signal.ts] -->|notifies| Computation
Computation[Computation<br>memo / effect] -->|reads| Signal
Computation -->|owned by| Owner[Owner / context]
Owner -->|registers| Cleanups[onCleanup]
Updates[runUpdates queue] -->|drains| Computation
Effects[runEffects queue] -->|user effects| Computation
Transition[TransitionState] -.->|optional concurrent path| Updates
Scheduler[scheduler.ts<br>MessageChannel] -.->|enableScheduling| EffectsA read of a signal inside a tracking scope (memo, effect, render function) registers the active Listener as an observer on the signal's observers array. A write enqueues observers for re-execution. batch, untrack, createRoot, and runWithOwner move the active Listener/Owner so that subscriptions are scoped correctly.
Render layers
packages/solid/src/render/ builds the component / control-flow / Suspense layer on top of the reactive runtime:
component.ts—createComponent,mergeProps,splitProps, the dev-component instrumentation ($DEVCOMP), and theParentComponent/FlowComponent/VoidComponenttypes.flow.ts— the<For>and<Index>control flows (the rest of<Show>,<Switch>,<Match>,<ErrorBoundary>live insignal.ts).Suspense.ts—<Suspense>and<SuspenseList>.hydration.ts— the shared hydration context that lets the renderer pause/resume during streamed SSR.
The compiler emits calls into solid-js/web for DOM output. That module re-exports the bulk of its low-level primitives from dom-expressions (the runtime sibling library, declared as a workspace devDependency and aliased through the rxcore import — see packages/solid/web/src/core.ts). Solid's own additions on top of that are Portal, Dynamic, createDynamic, the hydrate enabler, and re-exports of For/Show/etc. from solid-js.
Server rendering
When the node, deno, or worker export condition is active, solid-js resolves to the server build (packages/solid/src/server/):
reactive.ts— a stripped-down reactive system that fakescreateSignal,createMemo,createEffectto be synchronous and one-shot. Components run, their JSX resolves, and the result is serialized.rendering.ts—createComponent,For,Show,Switch,Match,Suspense,ErrorBoundary,mergeProps,splitProps,createResource,lazy, plus the SSR helpersescapeandresolveSSRNode.solid-js/webserver entry (packages/solid/web/server/index.ts) layersrenderToString,renderToStringAsync, andrenderToStreamon top, usingserovalto serialize promises, resources, and de-duplicate streamed data (see CHANGELOG 1.8.0).
The browser build of solid-js/web ships server-mock.ts (packages/solid/web/src/server-mock.ts) so that calls to renderToString from a browser-condition build error helpfully instead of silently returning empty strings.
Stores
packages/solid/store/ adds proxy-based reactive trees on top of solid-js:
store.tsdefinescreateStore,unwrap,setProperty, and the proxy traps that lazily allocate per-propertyDataNodesignals.mutable.tsaddscreateMutableandmodifyMutable, which apply mutations directly through proxysettraps wrapped inbatch.modifiers.tsprovidesproduce(Immer-style) andreconcile(deep diff for setting whole subtrees while preserving identity).server.tsis the server build that strips reactive subscription sosetStorebecomes a plain assign.
Alternative front ends
Two non-JSX entry points let Solid run without a compiler:
solid-js/h(packages/solid/h/src/index.ts) creates a HyperScripth()factory usingcreateHyperScriptfromhyper-dom-expressions.solid-js/html(packages/solid/html/src/index.ts) creates anhtml`` `` tagged template usingcreateHTMLfromlit-dom-expressions`.
Both wire the dom-expressions runtime primitives (spread, assign, insert, createComponent, etc.) re-exported through solid-js/web.
Universal rendering
solid-js/universal (packages/solid/universal/src/index.ts) re-exports createRenderer from dom-expressions/universal. With babel-preset-solid configured as generate: "universal", the compiler emits calls into a renderer of your choice — terminal, native, canvas, etc. The package adds mergeProps from solid-js to the returned renderer object so it has the full Solid surface.
Custom elements
solid-element (packages/solid-element/src/index.ts) is a thin layer over the component-register library. customElement(tag, defaults, Component) registers a class that, on connect, calls createRoot, builds reactive props for each declared attribute via createSignal, and uses insert from solid-js/web to mount the component into the element's render root.
Build pipeline
turbo.json orchestrates per-package builds. packages/solid/rollup.config.js produces 16 bundles for the various entry points × runtime conditions (browser/dev/server) — the configuration is the single source of truth for which files turn into which dist/*.js. A babel-plugin-transform-rename-import step rewrites the special rxcore import inside Solid's source to the local web/src/core directory at build time, so that the same source code can produce both the browser DOM build (using dom-expressions browser core) and the server build (using a server core that knows how to escape HTML).
For a deeper walkthrough of the build orchestration and tooling, see Tooling.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.