solid-js
SolidJSは、仮想DOMを使わない高速なUI構築ライブラリで、Reactからの移行も容易にし、SSRやサーバー機能を持つフルスタックアプリSolidStartにも対応、signals、effects、memosなどを活用して、より高性能なUIを開発するSkill。
📜 元の英語説明(参考)
SolidJS — fine-grained reactive UI library without a virtual DOM. Use when building high-performance UIs, choosing a React alternative with better reactivity primitives, or using SolidStart for full-stack apps with SSR and server functions. Covers signals, effects, memos, stores, and migration patterns from React.
🇯🇵 日本人クリエイター向け解説
SolidJSは、仮想DOMを使わない高速なUI構築ライブラリで、Reactからの移行も容易にし、SSRやサーバー機能を持つフルスタックアプリSolidStartにも対応、signals、effects、memosなどを活用して、より高性能なUIを開発するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o solid-js.zip https://jpskill.com/download/15398.zip && unzip -o solid-js.zip && rm solid-js.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/15398.zip -OutFile "$d\solid-js.zip"; Expand-Archive "$d\solid-js.zip" -DestinationPath $d -Force; ri "$d\solid-js.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
solid-js.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
solid-jsフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
SolidJS
概要
SolidJS は、JSX を実際の DOM 操作にコンパイルする宣言的な UI ライブラリです。仮想 DOM や差分比較は行いません。リアクティビティはきめ細かく、変更されたデータに依存する正確な DOM ノードのみが更新されます。その結果、React のようなオーサリング体験で、ネイティブに近いパフォーマンスを実現します。
インストール
# 新しい SolidJS プロジェクト
npx degit solidjs/templates/ts my-app
cd my-app
npm install
npm run dev
# または Vite を使用する場合
npm create vite@latest my-app -- --template solid-ts
リアクティビティプリミティブ
createSignal — リアクティブな状態
import { createSignal } from "solid-js";
// シグナルは getter/setter のペアです
const [count, setCount] = createSignal(0);
// 読み取り: 関数として呼び出す
console.log(count()); // 0
// 書き込み: setter を呼び出す
setCount(1);
setCount((prev) => prev + 1); // アップデーター関数
// オブジェクトを持つシグナル
const [user, setUser] = createSignal({ name: "Alice", age: 30 });
setUser((prev) => ({ ...prev, age: 31 }));
createEffect — 副作用
import { createSignal, createEffect } from "solid-js";
const [name, setName] = createSignal("Alice");
// 即座に実行され、依存関係が変更されるたびに再実行されます
createEffect(() => {
console.log("Name changed:", name());
document.title = `Hello, ${name()}!`;
});
// クリーンアップ関数
createEffect(() => {
const id = setInterval(() => console.log(name()), 1000);
return () => clearInterval(id); // 次のエフェクトの前または破棄時に実行されます
});
createMemo — 派生状態
import { createSignal, createMemo } from "solid-js";
const [price, setPrice] = createSignal(100);
const [quantity, setQuantity] = createSignal(3);
// 計算された値 — 依存関係が変更された場合にのみ再計算されます
const total = createMemo(() => price() * quantity());
console.log(total()); // 300
setPrice(120);
console.log(total()); // 360 — 再計算されました
制御フロー
import { Show, For, Switch, Match, Index } from "solid-js";
// Show — 条件付きレンダリング
<Show when={isLoggedIn()} fallback={<LoginForm />}>
<Dashboard />
</Show>
// For — リストのレンダリング (効率的なキー付き更新)
<For each={items()}>
{(item, index) => <div>{index()} - {item.name}</div>}
</For>
// Index — 項目がその場で変更される場合 (並べ替えではない) のリストのレンダリング
<Index each={items()}>
{(item, index) => <div>{index} - {item().name}</div>}
</Index>
// Switch/Match — 複数分岐の条件
<Switch fallback={<p>Unknown status</p>}>
<Match when={status() === "loading"}><Spinner /></Match>
<Match when={status() === "error"}><ErrorView /></Match>
<Match when={status() === "success"}><DataView /></Match>
</Switch>
Stores — 複雑な状態
import { createStore, produce } from "solid-js/store";
const [state, setState] = createStore({
users: [] as { id: number; name: string; active: boolean }[],
loading: false,
});
// ネストされたプロパティの更新
setState("loading", true);
setState("users", 0, "active", false);
// produce を使用した Immer のようなミューテーション
setState(
produce((s) => {
s.users.push({ id: 4, name: "Diana", active: true });
s.loading = false;
})
);
Resources — 非同期データフェッチ
import { createSignal, createResource, Suspense } from "solid-js";
// createResource — 非同期データフェッチをラップします
async function fetchUser(id: number) {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error("User not found");
return res.json();
}
function UserProfile() {
const [userId, setUserId] = createSignal(1);
// userId() が変更されると自動的に再フェッチされます
const [user, { refetch, mutate }] = createResource(userId, fetchUser);
return (
<Suspense fallback={<p>Loading...</p>}>
{/* user() はロード中は undefined で、準備ができたときに値になります */}
<Show when={user()} fallback={<p>Error loading user</p>}>
{(u) => (
<div>
<h1>{u().name}</h1>
<button onClick={refetch}>Refresh</button>
</div>
)}
</Show>
</Suspense>
);
}
SolidStart — フルスタック
SolidStart は、ファイルベースのルーティング、SSR、およびサーバー機能を追加します。
npm create solid@latest
# 選択: SolidStart, TypeScript
ファイル構造:
src/
routes/
index.tsx → /
about.tsx → /about
users/
index.tsx → /users
[id].tsx → /users/:id
app.tsx
// src/routes/users/[id].tsx
import { createAsync, useParams } from "@solidjs/router";
import { Show, Suspense } from "solid-js";
import { getUser } from "~/lib/users"; // サーバー機能
export default function UserPage() {
const params = useParams();
const user = createAsync(() => getUser(Number(params.id)));
return (
<Suspense fallback={<p>Loading...</p>}>
<Show when={user()}>
{(u) => (
<article>
<h1>{u().name}</h1>
<p>{u().email}</p>
</article>
)}
</Show>
</Suspense>
);
}
// src/lib/users.ts — サーバー機能
"use server";
export async function getUser(id: number) {
const res = await fetch(`https://api.example.com/users/${id}`);
return res.json();
}
export async function createUser(data: { name: string; email: string }) {
// サーバーでのみ実行されます — DB に安全にアクセスできます
return db.insert(users).values(data).returning();
}
Context (依存性注入)
import { createContext, useContext, type ParentComponent } from "solid-js";
import { createStore } from "solid-js/store";
const AuthContext = createContext<{ user: () => User | null; login: (u: User) => void }>();
export const AuthProvider: ParentComponent = (props) => {
const [state, setState] = createStore<{ user: User | null }>({ user: null });
const value = { user: () => state.user, login: (u: User) => setState("user", u) };
return <AuthContext.Provider value={value}>{props.children}</AuthContext.Provider>;
};
export const useAuth = () => useContext(AuthContext)!;
fr からの移行
(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
SolidJS
Overview
SolidJS is a declarative UI library that compiles JSX to real DOM operations — no virtual DOM, no diffing. Reactivity is fine-grained: only the exact DOM nodes that depend on changed data update. The result is near-native performance with a React-like authoring experience.
Installation
# New SolidJS project
npx degit solidjs/templates/ts my-app
cd my-app
npm install
npm run dev
# Or with Vite
npm create vite@latest my-app -- --template solid-ts
Reactivity Primitives
createSignal — Reactive State
import { createSignal } from "solid-js";
// Signals are getter/setter pairs
const [count, setCount] = createSignal(0);
// Read: call as function
console.log(count()); // 0
// Write: call setter
setCount(1);
setCount((prev) => prev + 1); // Updater function
// Signals with objects
const [user, setUser] = createSignal({ name: "Alice", age: 30 });
setUser((prev) => ({ ...prev, age: 31 }));
createEffect — Side Effects
import { createSignal, createEffect } from "solid-js";
const [name, setName] = createSignal("Alice");
// Runs immediately, then reruns whenever dependencies change
createEffect(() => {
console.log("Name changed:", name());
document.title = `Hello, ${name()}!`;
});
// Cleanup function
createEffect(() => {
const id = setInterval(() => console.log(name()), 1000);
return () => clearInterval(id); // Runs before next effect or on dispose
});
createMemo — Derived State
import { createSignal, createMemo } from "solid-js";
const [price, setPrice] = createSignal(100);
const [quantity, setQuantity] = createSignal(3);
// Computed value — only recalculates when dependencies change
const total = createMemo(() => price() * quantity());
console.log(total()); // 300
setPrice(120);
console.log(total()); // 360 — recalculated
Control Flow
import { Show, For, Switch, Match, Index } from "solid-js";
// Show — conditional rendering
<Show when={isLoggedIn()} fallback={<LoginForm />}>
<Dashboard />
</Show>
// For — list rendering (efficient keyed updates)
<For each={items()}>
{(item, index) => <div>{index()} - {item.name}</div>}
</For>
// Index — list rendering when items change in place (not reorder)
<Index each={items()}>
{(item, index) => <div>{index} - {item().name}</div>}
</Index>
// Switch/Match — multi-branch conditional
<Switch fallback={<p>Unknown status</p>}>
<Match when={status() === "loading"}><Spinner /></Match>
<Match when={status() === "error"}><ErrorView /></Match>
<Match when={status() === "success"}><DataView /></Match>
</Switch>
Stores — Complex State
import { createStore, produce } from "solid-js/store";
const [state, setState] = createStore({
users: [] as { id: number; name: string; active: boolean }[],
loading: false,
});
// Update nested properties
setState("loading", true);
setState("users", 0, "active", false);
// Immer-like mutations with produce
setState(
produce((s) => {
s.users.push({ id: 4, name: "Diana", active: true });
s.loading = false;
})
);
Resources — Async Data Fetching
import { createSignal, createResource, Suspense } from "solid-js";
// createResource — wraps async data fetching
async function fetchUser(id: number) {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error("User not found");
return res.json();
}
function UserProfile() {
const [userId, setUserId] = createSignal(1);
// Refetches automatically when userId() changes
const [user, { refetch, mutate }] = createResource(userId, fetchUser);
return (
<Suspense fallback={<p>Loading...</p>}>
{/* user() is undefined while loading, the value when ready */}
<Show when={user()} fallback={<p>Error loading user</p>}>
{(u) => (
<div>
<h1>{u().name}</h1>
<button onClick={refetch}>Refresh</button>
</div>
)}
</Show>
</Suspense>
);
}
SolidStart — Full-Stack
SolidStart adds file-based routing, SSR, and server functions:
npm create solid@latest
# Choose: SolidStart, TypeScript
File structure:
src/
routes/
index.tsx → /
about.tsx → /about
users/
index.tsx → /users
[id].tsx → /users/:id
app.tsx
// src/routes/users/[id].tsx
import { createAsync, useParams } from "@solidjs/router";
import { Show, Suspense } from "solid-js";
import { getUser } from "~/lib/users"; // server function
export default function UserPage() {
const params = useParams();
const user = createAsync(() => getUser(Number(params.id)));
return (
<Suspense fallback={<p>Loading...</p>}>
<Show when={user()}>
{(u) => (
<article>
<h1>{u().name}</h1>
<p>{u().email}</p>
</article>
)}
</Show>
</Suspense>
);
}
// src/lib/users.ts — server functions
"use server";
export async function getUser(id: number) {
const res = await fetch(`https://api.example.com/users/${id}`);
return res.json();
}
export async function createUser(data: { name: string; email: string }) {
// Runs on the server only — safe to access DB
return db.insert(users).values(data).returning();
}
Context (Dependency Injection)
import { createContext, useContext, type ParentComponent } from "solid-js";
import { createStore } from "solid-js/store";
const AuthContext = createContext<{ user: () => User | null; login: (u: User) => void }>();
export const AuthProvider: ParentComponent = (props) => {
const [state, setState] = createStore<{ user: User | null }>({ user: null });
const value = { user: () => state.user, login: (u: User) => setState("user", u) };
return <AuthContext.Provider value={value}>{props.children}</AuthContext.Provider>;
};
export const useAuth = () => useContext(AuthContext)!;
Migrating from React
| React | SolidJS |
|---|---|
useState(0) |
createSignal(0) |
useEffect(() => {}, [dep]) |
createEffect(() => { dep(); }) |
useMemo(() => calc, [dep]) |
createMemo(() => calc()) |
useReducer |
createStore |
useContext |
useContext (same API) |
React.memo |
Not needed — no re-renders |
key prop in lists |
Use <For> instead of map() |
useRef |
createSignal or let el!: HTMLElement |
Key differences:
- Components run once — no "re-render" concept. Put reactive logic inside JSX or effects.
- Access signals by calling them —
count()notcount. - Use
<For>for lists — not.map()— for efficient keyed rendering. - Destructuring signals breaks reactivity — pass signals or use stores.
Guidelines
- Never destructure signals:
const { x } = statebreaks reactivity. Usestate.xorcreateMemo. - Use
<For>instead ofArray.mapin JSX for efficient list rendering. - Components run once — initialize logic at the top level, not in callbacks.
- Use
createStorefor objects/arrays that need fine-grained updates. - Use
createResourcefor async data — it integrates with<Suspense>automatically. createMemois cached — prefer it over callingcreateEffectto compute derived values.- SolidStart
"use server"functions run exclusively on the server — safe for DB access.