SolidJS reactive UI library. Covers signals, effects, and fine-grained reactivity. USE WHEN: user mentions "SolidJS", "Solid", "createSignal", "createEffect", "createMemo", "fine-grained reactivity", asks about "Solid patterns", "reactive primitives" DO NOT USE FOR: React - use `frontend-react` (different API despite similar JSX), Vue - use `vue-composition`, Svelte - use `svelte`, Angular - use `angular`

GitHub
Install command
npx skhub add claude-dev-suite/solid
Markdown
SKILL.md

SolidJS Core Knowledge

Full Reference: See advanced.md for WebSocket primitive, context provider, chat component, room management, Socket.IO integration, and store patterns.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: solid for comprehensive documentation.

When NOT to Use This Skill

Skip this skill when:

  • Working with React (use frontend-react - APIs are different)
  • Building Vue applications (use vue-composition)
  • Using Svelte (use svelte)
  • Working with Angular (use angular)
  • Need server-side only logic (no framework needed)

Component Structure

import { createSignal, createEffect, createMemo } from 'solid-js';

interface Props {
  name: string;
  count?: number;
}

function Counter(props: Props) {
  const [localState, setLocalState] = createSignal('');
  const doubled = createMemo(() => (props.count ?? 0) * 2);

  createEffect(() => {
    console.log('Count changed:', props.count);
  });

  return (
    <div>
      <h1>Hello {props.name}</h1>
      <p>Doubled: {doubled()}</p>
      <button onClick={() => setLocalState('clicked')}>
        Click
      </button>
    </div>
  );
}

Reactivity Primitives

APIPurpose
createSignalReactive state
createMemoCached computation
createEffectSide effects
createResourceAsync data fetching
createStoreNested reactive objects

Key Differences from React

  • No Virtual DOM - fine-grained updates
  • Props are getters - access via props.name
  • No dependency arrays - auto-tracking
  • Components run once - not on every render
  • JSX compiles differently - expressions are reactive

Control Flow

import { Show, For, Switch, Match } from 'solid-js';

<Show when={isLoggedIn()} fallback={<Login />}>
  <Dashboard />
</Show>

<For each={items()}>{(item) => <Item data={item} />}</For>

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Destructuring propsLoses reactivityAccess via props.name
Using React patternsDifferent paradigmUse Solid primitives
Not using <Show> componentManual conditional logicUse <Show when={}>
Recreating signals in componentsComponents run onceCreate outside or use stores
Using innerHTML without sanitizationXSS vulnerabilityUse DOMPurify
Not cleaning up in onCleanupMemory leaksAdd cleanup logic

Quick Troubleshooting

IssueLikely CauseSolution
Props not reactiveDestructured propsAccess via props.name
Signal not updatingForgot to call setterUse setCount(newValue)
Effect not runningNot tracking signalCall signal inside effect: count()
Component re-runningTreating like ReactComponents run once, use signals
List not updatingUsing array methodsUse produce() from solid-js/store
Memory leaksNo cleanupUse onCleanup()

Production Readiness

Error Handling

import { ErrorBoundary } from 'solid-js';

function App() {
  return (
    <ErrorBoundary
      fallback={(err, reset) => (
        <div>
          <p>Error: {err.message}</p>
          <button onClick={reset}>Retry</button>
        </div>
      )}
    >
      <MainContent />
    </ErrorBoundary>
  );
}

Performance

// Lazy loading components
const HeavyComponent = lazy(() => import('./HeavyComponent'));

function App() {
  return (
    <Suspense fallback={<Loading />}>
      <HeavyComponent />
    </Suspense>
  );
}

// Batch updates (rarely needed)
import { batch } from 'solid-js';

batch(() => {
  setCount(count() + 1);
  setName('New Name');
});

Store Patterns

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

const [state, setState] = createStore({
  users: [] as User[],
  filters: { active: true },
});

// Immutable-style updates with produce
function addUser(user: User) {
  setState(produce((s) => {
    s.users.push(user);
  }));
}

// Path-based updates
setState('users', (users) => [...users, newUser]);
setState('filters', 'active', false);

Testing

import { render, screen } from '@solidjs/testing-library';
import userEvent from '@testing-library/user-event';
import Counter from './Counter';

describe('Counter', () => {
  it('increments on click', async () => {
    const user = userEvent.setup();
    render(() => <Counter initial={0} />);

    const button = screen.getByRole('button');
    await user.click(button);

    expect(screen.getByText('Count: 1')).toBeInTheDocument();
  });
});

Security

// innerHTML - only with trusted content
<div innerHTML={sanitizedHtml} />

// Prefer text content
<div>{userInput}</div> // Safe - auto-escaped

// XSS prevention
import DOMPurify from 'dompurify';

function SafeHtml(props: { html: string }) {
  const clean = () => DOMPurify.sanitize(props.html);
  return <div innerHTML={clean()} />;
}

Monitoring Metrics

MetricTarget
Bundle size< 30KB
First Contentful Paint< 1s
Time to Interactive< 1.5s
Memory usageStable

Checklist

  • ErrorBoundary for error handling
  • Suspense for async operations
  • Lazy loading for code splitting
  • createStore for complex state
  • Virtual lists for large data
  • No innerHTML with user input
  • Testing with @solidjs/testing-library
  • SSR with SolidStart
  • Fine-grained updates (no unnecessary re-renders)
  • Bundle analysis

Reference Documentation

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: solid for comprehensive documentation.

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/frontend-frameworks/solid

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1