Agent skill

Solid JS

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM.

MITAuto-check passedFrontend & Design

Install Solid JS

skills CLI
$ npx skills add ericrisco/rsc-harness --skill solid-js -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness solid-js --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/solid-js .claude/skills/solid-js && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
solid-js
GitHub stars
156
Token cost
~3.1k tokens
SKILL.md length
908 words
Files
6 (incl. scripts, references)
Skills in repo
229
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM.

  • Debugging a SolidJS app — signals
  • SKILL.md covers When to use / when not, The mental-model shift (read…, Signals — single reactive values and Props — the destructuring trap, plus 8 more sections
  • Runs Shell scripts from its folder; calls npm, bash and tsc
  • Memos and resources

What it does

Solid JS is an agent skill from ericrisco/rsc-harness. Use when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM. Covers the classic traps: a signal that does not update the UI, For versus Index, effect loops, components that run once, and props losing reactivity when destructured. NOT React's re-render model (that is react).

Its SKILL.md is about 3.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 8 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/reactivity-deep-dive.md`).

It sits in Frontend & Design, covering React components. It works with React, Vercel and TypeScript. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Debugging a SolidJS app — signals
  • Memos and resources
  • JSX that compiles to real DOM with no virtual DOM

Example prompts

  • “/solid-js”

Requirements

  • Node.js
  • A Bash shell

What it can do on your machine

Read from SKILL.md and the folder at commit 92fde8f. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • npm
    • bash
    • tsc

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Solid JS loads about 3.1k tokens when it runs, and up to ~4.8k if it reads all its reference files. Until then it costs about 96 tokens; SKILL.md has 908 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~96
When it runs · the whole SKILL.md, loaded when a task matches
~3.1k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~4.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit 92fde8f, republished under its MIT licence (© ericrisco). 908 words, ~3,119 tokens.

Download SKILL.mdSave it as .claude/skills/solid-js/SKILL.md (or your agent's skills folder). This skill also uses 5 other files; get the full folder from GitHub.
name
solid-js
description
Use when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM. Covers the classic traps: a signal that does not update the UI, For versus Index, effect loops, components that run once, and props losing reactivity when destructured. NOT React's re-render model (that is `react`).
tags
solidjs, signals, reactivity, frontend, jsx, web
recommends
vercel, testing-web, design
origin
risco

SolidJS — fine-grained reactivity, no VDOM

One rule governs everything else: the component function runs ONCE. Reactivity does not live in re-running the body — it lives in the reads. You read state by calling a getter (count()), and Solid re-runs only the exact DOM expression or effect that read it. There is no virtual DOM and no reconciliation; JSX compiles straight to DOM nodes. If you carry React habits here (destructuring props, expecting the body to re-run, deriving state in an effect), reactivity breaks silently — the code runs, it just stops updating.

Versions: stable is solid-js 1.9.x (1.9.11/1.9.13 line). Solid 2.0 is in beta on the next npm tag with a new reactive core (@solidjs/signals), createAsync, and automatic batching. Default to 1.9.x APIs unless the task says 2.0; flag the divergence where it matters.

When to use / when not

SituationSkill
Solid signals/stores/effects/memos/resources, JSX-to-DOM, <For>/<Index>this skill
React useState/hooks/re-render model (the body re-runs)react
Next.js routing, server actions, RSCnextjs
Svelte 5 $state/$derived runes (similar look, different compiler)svelte
Vue/Nuxt ref/reactive/computedvue-nuxt
Astro island architecture / what ships to the client (can host a Solid island)astro
Plain TypeScript questions with no Solid surface../typescript/SKILL.md
Deploying the built app (Vercel/SolidStart adapter)../vercel/SKILL.md

The mental-model shift (read this first)

React re-runs the component body on every state change; Solid runs it once and re-runs only the tracked reads. So the value is the call, not the variable.

tsx
// Bad — React reflex: treats `count` as a value, body assumed to re-run.
function Counter() {
  const [count, setCount] = createSignal(0);
  console.log("body ran");        // prints ONCE, ever
  return <button onClick={() => setCount(count + 1)}>{count}</button>;
  //                                          ^ NaN: count is the getter fn, not a number
}

// Good — read by calling the getter; the JSX read is what re-runs.
function Counter() {
  const [count, setCount] = createSignal(0);
  return <button onClick={() => setCount((c) => c + 1)}>{count()}</button>;
  //                                                      ^ tracked read
}

Why: the body is setup that runs once. Only getter reads inside JSX, effects, or memos are tracked and re-executed. count is the accessor function; count() is its current value.

Signals — single reactive values

createSignal(initial) returns [getter, setter]. Read with getter(), write with setter(next) or setter(prev => next).

tsx
const [name, setName] = createSignal("Ada");
setName("Grace");          // replace
setName((n) => n + "!");   // update from previous

Derived state is just a function — no API needed:

tsx
const [first, setFirst] = createSignal("Ada");
const [last, setLast]  = createSignal("Lovelace");
const fullName = () => `${first()} ${last()}`;   // re-reads on access, always fresh

Reach for createMemo only when the computation is expensive or shared by many readers — it caches and re-runs only when its dependencies change:

tsx
const sorted = createMemo(() => [...items()].sort(byName));  // expensive: memoize

Rule: derive with a plain () => … by default; promote to createMemo for cost/sharing. Why: a memo adds a reactive node; a plain function is free and recomputes lazily on read.

Props — the destructuring trap

Props are a reactive proxy. Destructuring or assigning .x reads the value once at run-once time, freezing it.

tsx
// Bad — both snapshot a dead value; updates from the parent never arrive.
function Hi(props) { const { name } = props; return <p>{name}</p>; }
function Hi(props) { const name = props.name; return <p>{name}</p>; }

// Good — read inline, or wrap in an accessor to pass reactivity along.
function Hi(props) { return <p>{props.name}</p>; }
function Hi(props) { const name = () => props.name; return <p>{name()}</p>; }

To split or default props while keeping reactivity, use splitProps / mergeProps — never the spread/destructure idiom:

tsx
import { splitProps, mergeProps } from "solid-js";

function Button(props) {
  const merged = mergeProps({ variant: "primary" }, props);   // reactive defaults
  const [local, rest] = splitProps(merged, ["variant", "children"]);
  return <button class={local.variant} {...rest}>{local.children}</button>;
}

Why: splitProps/mergeProps return proxies that preserve getter tracking; { ...props } and const { x } = props collapse it to a one-time copy.

Stores — nested object / array state

createSignal is for one value. Use createStore for nested objects or arrays so updates are fine-grained per path (only the components reading the changed leaf re-run), with no cloning of the whole tree.

tsx
import { createStore, produce } from "solid-js/store";

const [state, setState] = createStore({ user: { name: "Ada" }, todos: [] });

setState("user", "name", "Grace");               // path update — only name readers re-run
setState("todos", (t) => [...t, { id: 1, done: false }]); // append
setState("todos", 0, "done", true);              // update one item field by index
setState(produce((s) => { s.todos[0].done = true; }));    // mutate-style, still fine-grained
tsx
// Bad — replacing the whole object kills path-level reactivity and re-renders everything.
setState({ user: { name: "Grace" }, todos: state.todos });

// Good — target the path that changed.
setState("user", "name", "Grace");

Why: stores diff at the path you touch; whole-object replacement is a single coarse change that defeats the entire point of a store.

Effects & lifecycle — side effects only

createEffect runs after render and re-runs when any signal it reads changes. It is for side effects (DOM, logging, subscriptions, network) — not for computing state.

tsx
createEffect(() => {
  document.title = `Count: ${count()}`;   // side effect, tracks count()
});

onMount(() => {                            // runs once after first render
  const id = setInterval(tick, 1000);
  onCleanup(() => clearInterval(id));      // before re-run AND on disposal
});

batch(() => { setA(1); setB(2); });        // one update pass instead of two (1.x; auto in 2.0)
const snapshot = untrack(() => raw());     // read without subscribing

The signature anti-pattern — deriving state by writing a signal inside an effect — causes an infinite loop and is the most common "Solid is broken" report:

tsx
// Bad — effect reads total(), writes total → re-triggers itself forever.
const [total, setTotal] = createSignal(0);
createEffect(() => setTotal(price() * qty()));

// Good — derive, don't store.
const total = createMemo(() => price() * qty());   // or: const total = () => price() * qty();

Why: an effect that writes one of its own dependencies is a feedback loop. Derived values are reads, not writes.

Show full SKILL.md (374 more words)Show less

Control flow — use Solid's primitives, not raw JS

Early return, bare &&, and .map() defeat tracking or leak falsy values. Use the components, which Solid can track and dispose precisely.

tsx
<Show when={user()} fallback={<Login />}>{(u) => <Profile user={u()} />}</Show>
<Switch fallback={<NotFound />}>
  <Match when={state() === "loading"}><Spinner /></Match>
  <Match when={state() === "ready"}><Data /></Match>
</Switch>
<Dynamic component={tagFor(kind())} {...props} />

<For> vs <Index> is a real decision:

Your list is…UseWhy
Keyed objects that reorder/insert/remove<For each={items()}>{(item) => …}</For>keys by reference; DOM nodes move, not rebuild
Fixed-position rows, primitives, or inputs bound to the index<Index each={items()}>{(item) => … item() …}</Index>keys by position; item is an accessor (item())
tsx
// Bad — <For> with index-bound inputs: nodes move on reorder, inputs desync.
<For each={fields()}>{(f, i) => <input value={f.value} onInput={(e) => setField(i(), e)} />}</For>

// Good — <Index> when the position is the identity.
<Index each={fields()}>{(f, i) => <input value={f().value} onInput={(e) => setField(i, e)} />}</Index>

Why: <For> tracks which value lives where (great for keyed data); <Index> tracks what's at slot N (great for fixed slots). Picking wrong rebuilds or desyncs nodes.

Async — resources + Suspense

In 1.x use createResource; in 2.0 the standard primitive is createAsync. Both surface loading/error through <Suspense> and <ErrorBoundary>.

tsx
// 1.x
const [user] = createResource(userId, (id) => fetchUser(id));   // refetches when userId() changes

<ErrorBoundary fallback={(err) => <p>Failed: {err.message}</p>}>
  <Suspense fallback={<Spinner />}>
    <p>{user()?.name}</p>
  </Suspense>
</ErrorBoundary>

The 1.9→2.0 async migration (createAsync, automatic batching, @solidjs/signals) lives in references/reactivity-deep-dive.md.

Project setup

bash
npm create vite@latest my-app -- --template solid-ts   # Vite + vite-plugin-solid + TS
cd my-app && npm install && npm run dev

Routing with @solidjs/router:

tsx
import { Router, Route, A } from "@solidjs/router";

function App() {
  return (
    <Router>
      <Route path="/" component={Home} />
      <Route path="/users/:id" component={UserPage} />
    </Router>
  );
}
// inside UserPage: const params = useParams(); params.id  (reactive)
// nav links use <A href="…"> (not raw <a>) for client-side routing

For SSR, file-based routing, and server functions ("use server", query/action), reach for SolidStart (1.x stable; 2.0.0-alpha tracks Solid 2.0). The full router + SolidStart map is in references/router-and-start.md. Deploying the build → ../vercel/SKILL.md.

Anti-patterns

Anti-patternWhy it breaksDo instead
const { x } = props / const x = props.xsnapshots a non-reactive value at run-onceread props.x inline or const x = () => props.x
Reading count instead of count()passes the accessor function, not the valuecall it: count()
Expecting the component body to re-runit runs once; only tracked reads re-runmove reactive work into JSX / effect / memo
Deriving state via createEffect that sets a signalfeedback loop / stale ordercreateMemo or a plain () => …
<For> for index-bound inputsnodes move on reorder, inputs desync<Index> (keyed by position, item())
setStore(wholeNewObject)one coarse change defeats fine-grained pathssetStore("path", …, value) / produce
Early return null / cond && <X/> for conditionalsleaks falsy values, escapes tracking<Show when={…} fallback={…}> / <Switch>
{...props} to forward reactivelyspread copies once, drops getterssplitProps / mergeProps

Verify

If the project emits Solid components/JSX/config, run the gate:

bash
bash scripts/verify.sh

It detects the package runner from the lockfile, then runs tsc --noEmit → ESLint → Vitest → vite build. Missing tools are SKIPPED (yellow), not failed; it exits non-zero only on a real failure.

References

  • references/reactivity-deep-dive.md — ownership & disposal, createRoot/getOwner/runWithOwner, on() explicit deps, createComputed/createRenderEffect, createSelector, store reconcile/produce, and the 1.9→2.0 migration.
  • references/router-and-start.md — full @solidjs/router surface (params, data loading, navigation, nested layouts) and a concise SolidStart 1.x map.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 5 other files (scripts, references) in skills/solid-js of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/reactivity-deep-dive.md
  • references/router-and-start.md
  • scripts/verify.sh

Open the folder on GitHubat commit 92fde8f

Compare with similar skills

Solid JS next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Solid JS compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Solid JS this skillericrisco/rsc-harness156—~3.1kAutomated safety check: PassMIT
Vercel React Best Practicessanity-io/sanity6.4k130 repos~1.6kAutomated safety check: PassMIT
React Render Types CompositionHorusGoul/eslint-plugin-react-render-types111—~1.1kAutomated safety check: PassMIT
Safe Element Comparisonseasonedcc/remix-forms514—~1.8kAutomated safety check: PassMIT
React Best Practicesryokun6/ryos1.3k—~2kAutomated safety check: PassMIT
Frontend Typescript Rulesshinpr/ai-coding-project-boilerplate232—~1.7kAutomated safety check: PassMIT

Similar skills

  • Official

    React and Next.js performance optimization guidelines from Vercel Engineering.

    6.4k GitHub starsUsed in 130 repos~1.6k tokens
    Frontend & DesignAuto-check passed
  • React Render Types Composition

    HorusGoul/eslint-plugin-react-render-types

    Composition patterns for building React components with @renders type annotations from eslint-plugin-react-render-types.

    111 GitHub stars~1.1k tokensUpdated 2 mo ago
    Frontend & DesignAuto-check passed
  • Safe Element Comparison

    seasonedcc/remix-forms

    Maintain element type comparison safety in remix-forms. An agent skill from seasonedcc/remix-forms.

    514 GitHub stars~1.8k tokensUpdated 5 mo ago
    Frontend & DesignAuto-check passed
  • React performance optimization guidelines from Vercel Engineering (vercel-labs/agent-skills).

    1.3k GitHub stars~2k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Frontend Typescript Rules

    shinpr/ai-coding-project-boilerplate

    Applies React/TypeScript type safety, component design, and state management rules.

    232 GitHub stars~1.7k tokensUpdated 3 days ago
    Frontend & DesignAuto-check passed
  • Vercel React Best Practices

    gambitph/Stackable

    React performance optimization guidelines from Vercel Engineering.

    350 GitHub stars~2k tokensUpdated today
    Frontend & DesignAuto-check passed

More from ericrisco/rsc-harness

All 229 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    156 GitHub stars~2.4k tokensUpdated yesterday
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    156 GitHub stars~3.4k tokensUpdated yesterday
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    156 GitHub stars~2.2k tokensUpdated yesterday
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    156 GitHub stars~3.2k tokensUpdated yesterday
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    156 GitHub stars~3.3k tokensUpdated yesterday
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    156 GitHub stars~2.8k tokensUpdated yesterday
    Auto-check passed

Questions about Solid JS

What does Solid JS do?

A skill your agent uses when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM. Solid JS is an agent skill from ericrisco/rsc-harness. Use when building, reviewing or debugging a SolidJS app — signals, stores, effects, memos and resources, and JSX that compiles to real DOM with no virtual DOM.

When should I use Solid JS?

Solid JS fits situations like: debugging a SolidJS app — signals; memos and resources; JSX that compiles to real DOM with no virtual DOM.

How do I install Solid JS in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill solid-js -a claude-code`. Or copy the skill folder (skills/solid-js in ericrisco/rsc-harness) into .claude/skills/solid-js in your project. Claude Code loads it when a task matches its description.

How do I install Solid JS in Codex?

Run `npx skills add ericrisco/rsc-harness --skill solid-js -a codex`. Or copy the skill folder (skills/solid-js in ericrisco/rsc-harness) into .agents/skills/solid-js in your project. Codex loads it when a task matches its description.

Can I use Solid JS in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill solid-js -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/solid-js, .gemini/skills/solid-js, .github/skills/solid-js and .opencode/skills/solid-js in your project.

What does Solid JS need to run?

Going by SKILL.md and its folder, Solid JS needs a shell for the scripts in its folder and the command-line tools its instructions call (npm, bash and tsc). Our summary lists: Node.js; A Bash shell.

Does Solid JS access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Solid JS safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Solid JS use?

Solid JS is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Solid JS use?

About 3.1k tokens (SKILL.md is roughly 12k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 1.6k tokens, read only when the agent opens those files.

What are the alternatives to Solid JS?

Skills that share tags, products or a category with Solid JS: Vercel React Best Practices (sanity-io/sanity, 6.4k stars), React Render Types Composition (HorusGoul/eslint-plugin-react-render-types, 111 stars), Safe Element Comparison (seasonedcc/remix-forms, 514 stars) and React Best Practices (ryokun6/ryos, 1.3k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Solid JS?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 156 GitHub stars. The repository holds 229 skills in this directory. The repository was last updated on October 6, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.