agentsclimarketplace

Solid expert

Skill Akayashuu/agent-skills/skills/solid-expert

Framework & language expert skills for Claude Code — idiomatic best practices for TypeScript, React, Vue, Svelte, Solid, Angular, Astro

Install
npx -y skills add Akayashuu/agent-skills --skill solid-expert

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when writing, reviewing, or debugging SolidJS — using createSignal/createMemo/createEffect, fine-grained reactivity, stores, props, or when reactivity silently stops updating.

SKILL.md

6.4 KB, as published. Nobody here has run it

SolidJS Expert

Overview

The #1 trap is treating Solid like React. Components run ONCE. There is no re-render, no virtual DOM, no dependency arrays. Reactivity is fine-grained: reading a signal inside a tracking scope (JSX, createMemo, createEffect) subscribes that exact spot, and only that spot updates. Most "Solid isn't updating" bugs come from breaking the subscription — destructuring props or reading a signal in code that runs once.

Quick Reference

GoalDoAvoid
Read a signalcall it: count()count (that's the getter, not the value)
Use propsprops.x lazily, or splitProps/mergePropsdestructuring { x } (kills reactivity)
Derived/expensive valuecreateMemo(() => …)recompute inline every read
Side effectcreateEffect (runs after render, tracks deps)doing effects in component body
Render a list<For each={items()}>items().map(...)
Conditional<Show when={ok()}>{ok() && …} ternary in once-run code
Nested reactive statecreateStore + path settersa signal holding a big object
Explicit dependencieson(dep, handler)relying on implicit tracking
Opt out of trackinguntrack(() => …)reading then ignoring
Async datacreateResource(source, fetcher)manual fetch in createEffect

Core Patterns

Don't destructure props — it snapshots the value once and breaks reactivity:

// ❌ name is read once at call time; later updates never reach the DOM
function Hello({ name }: { name: string }) {
  return <h1>Hello {name}</h1>
}
// ✅ access lazily, or splitProps to keep reactive proxies intact
function Hello(props: { name: string; class?: string }) {
  const [local, rest] = splitProps(props, ['name'])
  return <h1 {...rest}>Hello {local.name}</h1> // re-reads on change
}

Signals are getters — call them, and call them inside a tracking scope:

// ❌ destructured + read once in body; the <p> never updates
function Counter() {
  const [count] = createSignal(0)
  const doubled = count() * 2          // runs once, frozen
  return <p>{doubled}</p>
}
// ✅ read inside JSX (a tracking scope) or a memo — see runnable example

Runnable: examples/counter.tsx

<For> over .map() — keyed by reference, rows persist instead of re-creating:

// ❌ .map() is evaluated once; the list never re-renders on change
<ul>{users().map(u => <li>{u.name}</li>)}</ul>
// ✅ <For> diffs by reference (use <Index> when keyed by position instead)
<For each={users()}>{(u) => <li>{u.name}</li>}</For>

<For> is keyed by item identity (reorders move DOM nodes); <Index> is keyed by position (the item is a signal () => T) — use it for primitives or fixed-length lists.

createStore for nested objects — fine-grained, only touched paths update:

setState('user', 'name', 'Grace')              // path setter, surgical
setState('user', 'tags', produce(t => t.push('b'))) // mutate-style via produce

Runnable: examples/store-nested.ts

createResource for async — the idiomatic data fetch, not fetch in an effect:

// source is a signal/accessor; when it changes (and isn't false/null/undefined)
// the fetcher re-runs. Returns [resource, { mutate, refetch }].
const [user] = createResource(userId, (id) => fetch(`/u/${id}`).then(r => r.json()))
// user() is the data; .loading / .error are reactive

Runnable: examples/resource-fetch.tsx

mutate(v) writes optimistically; refetch() reloads. Pairs with <Suspense> and <ErrorBoundary>.

Common Mistakes

  • Destructuring props — the canonical Solid bug. Keep props whole; use mergeProps for defaults, splitProps to forward.
  • Reading a signal without calling it{count} renders the function, never updates. It's {count()}.
  • .map()/ternary instead of <For>/<Show> — runs once, won't react. Control-flow components subscribe.
  • Expecting the component body to re-run — it runs once. Put reactive reads in JSX, createMemo, or createEffect.
  • Effects to compute values — use createMemo. Reserve createEffect for genuine side effects (DOM, logging, fetch).
  • createEffect writing a signal it reads — infinite loops; reach for on() with defer, or untrack. Batch grouped writes with batch.

When NOT to over-engineer

createMemo has bookkeeping cost — don't wrap cheap expressions (a() + b()); only memo expensive work or values feeding many subscribers. A plain () => … derived accessor is often enough. Use createStore for genuinely nested state; a single signal is fine for flat values. Reach for on()/untrack/batch only when implicit tracking actually misbehaves, not preemptively.

Reusable primitives

primitives.ts (same dir) — typed, SSR-safe createPersistedSignal (localStorage-backed signal, cross-tab sync) and createEventListener (auto-cleaned binding). Both use onCleanup so listeners die with their owner; copy/adapt rather than re-deriving the lifecycle each time.

Version note

Stable is Solid 1.9.x (everything above targets it). Solid 2.0 is in beta (solid-js@next): async becomes first-class (computations/createMemo can return Promises, reworked <Suspense>, deterministic batching). The 1.9 mental model — components run once, signals are getters, don't destructure props — carries forward; don't adopt 2.0 APIs in production yet.

Sources

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.