framework/solid
SolidJS Online IDE for Fine-Grained Reactive Apps
JSX is compiled by babel-preset-solid into fine-grained DOM updates — the same compiler Solid uses locally, so a signal changes one text node instead of re-rendering a component.
import { createSignal, createMemo } from 'solid-js';
export function Counter() {
const [count, setCount] = createSignal(0);
const doubled = createMemo(() => count() * 2);
// the body runs once; only the text node
// below updates when count() changes.
return (
<button onClick={() => setCount(count() + 1)}>
{count()} · {doubled()}
</button>
);
}
01 platform
Why SolidJS feels different from a virtual DOM
Solid looks like React and behaves nothing like it underneath. The editor is built to make that difference visible while you learn it — write a signal, try it, and watch one node change — not to hide it behind a preview pane.
-
The component runs once
A Solid component is setup code, not a render function. It executes a single time to wire up reactivity; there is no re-render, no dependency array to get wrong, and no
useMemoneeded to stop one. -
Signals update the DOM directly
A
createSignalis read as a function —count()— and Solid tracks exactly where it is used. When it changes, the one text node or attribute that depends on it updates, and nothing else is touched. -
The real compiler, in the browser
JSX is transformed by
babel-preset-solidwithgenerate: "dom", the same preset a local Solid build uses. What runs here is what would run on your machine, not an approximation of it. -
Private and installable
The project lives in your browser, never on a server, and XCODX installs as a PWA — so a Solid experiment keeps working offline and stays yours.
02 deep dive
Signals, and why a component runs once
The mental model is the whole point of Solid, so the editor shows it working rather than describing it.
A signal is a getter and a setter. const [count, setCount] = createSignal(0) gives you a function to read and a function to write. Reading it inside JSX subscribes that exact spot in the DOM; writing it updates only those spots.
createMemo derives without recomputing the world. A memo re-runs only when a signal it read actually changes, and only the DOM that reads the memo updates in turn. There is no diffing pass, because there is no tree to diff.
Effects are explicit. createEffect runs when its tracked signals change — the place for a side effect — while everything else in the component body has already run and will not run again.
- read
- count() subscribes
- write
- setCount() updates
- derive
- createMemo, cached
- effect
- createEffect, tracked
const [q, setQ] = createSignal('');
// each reader re-runs on its own, only when q() moves
const trimmed = createMemo(() => q().trim());
const isEmpty = createMemo(() => trimmed() === '');
createEffect(() => {
console.log('query is now:', trimmed());
});
03 pipeline
How babel-preset-solid turns JSX into DOM
Four stages, all client-side. Solid's JSX does not become createElement calls — it becomes real DOM operations, and knowing that is what makes the output readable.
-
Parse
Your
.jsxis read by Babel in the browser. Solid needs a full syntax tree — unlike Sucrase, which the React pages use — because it rewrites JSX into DOM instructions rather than function calls. -
Transform
babel-preset-solidwithgenerate: "dom"turns each element into a cloned template plus fine-grained bindings, so a change updates one node instead of re-running a render. -
Resolve
Imports are matched against the project's import map.
solid-jsand anything you install from npm resolve to esm.sh URLs; a missing module is named here rather than at runtime. -
Run
The compiled module mounts with
renderfromsolid-js/web. Signals wire themselves to the DOM they touched, and the preview updates from there with no further compile.
04 features
What a SolidJS project starts with
Everything below is on the moment you open the Solid editor — including the sortable, filterable data table the starter ships as a worked example of fine-grained updates.
-
npm without a terminal wait
Search a package, click install.
@solidjs/router,solid-js/storeand the wider ecosystem resolve through esm.sh into a native import map, usable on the next render with nonode_modules. -
Live preview, four ways
Full width while you focus, split beside the code, inside real device frames, or in its own tab — so a fine-grained update is something you can actually watch happen.
-
TypeScript when you want it
Rename a file to
.tsxand keep going. The Solid preset strips annotations on the same pass it compiles JSX, so types cost nothing at compile time. -
The VS Code engine
Monaco brings IntelliSense, multi-cursor, the command palette and Prettier — the editor Visual Studio Code is built on, not a textarea with highlighting.
-
Real Git in the browser
Stage, commit, branch and read history through isomorphic-git, offline, and import an existing repository without leaving the tab.
-
Stores for bigger state
createStoregives nested, fine-grained reactive objects for state that has outgrown a handful of signals, and it is available the moment you import it.
05 deep dive
State that scales past a single signal
Signals are the primitive; stores are how a real Solid app keeps a tree of state fine-grained.
createStore is fine-grained all the way down. Update one field of a nested object and only the readers of that field update — the rest of the tree, and the DOM it drives, stays untouched. It is the same reactivity as a signal, applied to structured data.
Setter paths are surgical. setState('todos', 2, 'done', true) changes one property of one item, and Solid updates exactly the node that showed it. There is no immutable copy of the whole array to produce first.
Routing and data fit the same model. @solidjs/router and createResource install from npm and hang off the same signals, so an async fetch or a route change is just another tracked value the DOM reads.
- primitive
- createSignal
- structured
- createStore
- async
- createResource
- routing
- @solidjs/router
import { createStore } from 'solid-js/store';
const [state, setState] = createStore({
todos: [{ text: 'ship', done: false }],
});
// updates only the 'done' cell in the DOM:
setState('todos', 0, 'done', true);
06 workflow
From an empty tab to a reactive table
No scaffolding, no dependency install, no dev server — the whole loop from new project to a running, sortable table.
- new project → SolidJS
- created Counter.jsx, index.jsx, index.html
- install @solidjs/router
- resolved via esm.sh · import map updated · 0 files written
- save Table.jsx
- solid: jsx → dom 3ms (babel-preset-solid)
- preview reloaded · sort click updates 1 column
- git commit -m "filterable table"
- [main 9d2c1a7] filterable table · 4 files changed
-
Nothing to keep alive
There is no dev server process to restart, because there is no process — the compile happens in a worker beside the editor.
-
The same loop on a tablet
The compiler runs client-side, so an iPad compiles Solid JSX the same way a laptop does, with no local toolchain.
-
Share by link
Send a live preview URL and the other person sees the running table, not a screenshot of it.
07 ecosystem
SolidJS among the frameworks it resembles
Solid shares JSX with React and a compiler-first philosophy with Svelte, and the same editor picks the right compiler per file for any of them.
08 languages
Everything the editor understands beside Solid
Fine-grained reactivity is one file type among many the editor compiles, renders or runs for you.
Compiled in your browser11
Zero build step. Transform runs on a Web Worker, so typing never blocks.
- JSX
- TSX
- TypeScript
- Vue SFC
- Svelte
- Angular (JIT)
- SolidJS
- SCSS
- Sass
- Less
- Pug
Rendered natively8
Straight to the live preview, no transform in the way.
- HTML
- CSS
- JavaScript
- JSON
- Markdown
- Jupyter (.ipynb)
- SVG
- YAML
Executed on demand22
70+ languages run through a self-hosted Piston engine. stdout, stderr, images and tracebacks land in the console.
- Python
- Java
- C
- C++
- C#
- Go
- Rust
- Ruby
- PHP
- Kotlin
- Swift
- Lua
- Scala
- Perl
- Haskell
- Elixir
- Dart
- R
- Julia
- SQLite
- Bash
- PowerShell
09 questions
SolidJS in the browser — common questions
Does XCODX compile Solid with the real Solid compiler?
Yes. Solid's JSX is transformed by babel-preset-solid with generate: "dom" — the same preset a local Solid project uses — so it produces fine-grained DOM updates, not React-style createElement calls. What runs here is genuine Solid, not a lookalike.
Why does my Solid component only run once?
That is by design. A Solid component is setup code that wires reactivity, not a render function that re-runs. Reading a signal in JSX subscribes that spot in the DOM, so updates are surgical and there is no dependency array to manage.
Can I install Solid libraries like @solidjs/router?
Yes. Search the npm panel and install; XCODX resolves the package through esm.sh into a native import map. @solidjs/router, solid-js/store and createResource all import normally, with no node_modules folder.
Can I use TypeScript with SolidJS here?
Yes. Use .tsx files and write annotations as usual. The Solid preset strips the types on the same pass it compiles JSX, so there is no separate type-check step slowing the loop down.
How is a signal different from React state?
A signal is read as a function and tracked at the point of use, so setting it updates only the DOM that read it. React state triggers a component re-render that a virtual DOM then diffs. Solid skips the render and the diff entirely.
Does createStore work for nested state?
Yes. createStore gives a fine-grained reactive object: a setter path like setState('todos', 0, 'done', true) updates one property and the single DOM node that showed it, without copying the whole structure first.
Is this a good place to learn SolidJS?
Yes, because the setup that usually gets in the way is gone. The first thing you do is write a component and watch a signal update one node, which is the idea the rest of Solid builds on, with nothing to install first.
Can I run Solid's server-side rendering here?
No. Solid's SSR and SolidStart render on a server before the response is sent, which needs a running Node process rather than a browser tab. Everything client-side — signals, stores, routing, resources — works normally.
Do I need to install anything to use XCODX Studio?
No. XCODX Studio is a browser-based IDE — the editor, the compilers and the preview all run client-side. There is no download, no package manager to set up and no configuration file to write. Opening the editor is the whole setup step.
Where is my code stored?
In your own browser. Projects, file history and Git objects live in local storage on your device and are never uploaded to a server. That also means XCODX works offline: it is a Progressive Web App, so you can install it and keep coding with no connection.
Is XCODX Studio free?
Yes. The editor, the live preview, the 70+ language runtimes, npm installs, Git and the integrated terminal are all free to use.
Can I use XCODX on a tablet or Chromebook?
Yes. The editor is a responsive web app, so a Chromebook, an iPad or an Android tablet gets the same compilers and the same preview a laptop does — there is no desktop-only build, because there is no build to install at all. The layout adapts to the screen rather than shrinking a desktop UI into it.
Can I export a project or move it to my own machine?
Yes. Export the whole project as a zip with its folder structure intact and open it locally, or commit it and push. It is ordinary source on disk from that point on — no proprietary format and no lock-in, which is also why importing an existing repository from GitHub works the same way in reverse.
Nothing to install
Start building with SolidJS now
A reactive component on screen in under a minute — compiled by the real Solid preset, with no account wall and nothing to install.
