solid
Write, refactor, review, or test Solid 2 UI in OpenClaw (Control UI, plugin views, Canvas hosts), including state ownership, native custom elements, overlays…
Skill by openclaw
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/openclaw-solid
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, testing, writing
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/solid
What's inside
- Skill name
solid- Description
- Write, refactor, review, or test Solid 2 UI in OpenClaw (Control UI, plugin views, Canvas hosts), including state ownership, native custom elements, overlays, testing, performance, and lessons learned.
- License
- MIT
- Instructions
- 114 lines in SKILL.md · view on GitHub
Files (11)
- SKILL.md
- async-and-actions.md · references/
- components.md · references/
- idioms.md · references/
- lessons.md · references/
- overlays.md · references/
- performance.md · references/
- plugins.md · references/
- refactor-checklist.md · references/
- state-and-ownership.md · references/
- testing.md · references/
SKILL.md (first lines)
# Solid 2 in OpenClaw
The Control UI and plugin views (`extensions/x`, `extensions/workboard`) render with **Solid 2** (`solid-js`, `@solidjs/web`, `@solidjs/signals`, compiled by `@solidjs/vite-plugin`/`@solidjs/compiler`). Lit and Web Awesome are removed from these surfaces; new code is Solid only. The Canvas hosts also use Solid.
Read [ui/AGENTS.md](../../../ui/AGENTS.md) first; its state-ownership rules apply to Solid unchanged. Use the exact installed Solid pins from the owning `package.json`: the runtime and compiler are `2.0.0-rc.18`, and `@solidjs/vite-plugin` is `3.0.0-next.51`. `@solidjs/testing-library` remains `1.0.0-beta.3`. `solid-js` and `@solidjs/*` are exempt from the repository's seven-day release-age gate (Peter, 2026-10-11). Peter also approved exact-version exceptions for `seroval@1.7.0` and `seroval-plugins@1.7.0` on 2026-10-24: rc.18 requires them for SSR/hydration serialization. Other third-party Solid ecosystem packages remain subject to the gate.
## Rules that keep the UI correct
**Before your first edit**, read the installed `ui/node_modules/solid-js/CHEATSHEET.md`, especially its "What changed from 1.x" list. It is the rc.18 API contract, written as a guard against React and Solid 1 priors, the two dominant bug sources. For new code or a Solid audit, then read [idioms](references/idioms.md) and [lessons](references/lessons.md); to refactor or review existing code, also use the [refactor checklist](references/refactor-checklist.md). Check `solid-js/types/client/flow.d.ts` and the installed `@solidjs/signals` / `@solidjs/web` types when choosing an API. rc.18 has no `createAsync`: asynchronous values are ordinary computations returning promises or async iterables. `createDeferred` explicitly permits stale answers during refetch; use it only when that lag is the intended presentation contract.
For async reads, mutations, keyed projections, lazy components, or coordinated loading, read the [async and action recipes](references/async-and-actions.md). Cron is the worked reference: plain owners admit requests and writes; Solid presents their readiness and optimistic transitions.
For lists, derivations, copies, or anything on a hot path, read [performance](references/performance.md).
1. **Domain owners stay plain TypeScript.** The Gateway store, capabilities, `lib/sessions/*`, caches, persistence, and mutation authority keep synchronous mutate-then-read semantics. Solid 2 writes become visible only after a microtask flush, so authoritative state never lives in a signal. → [state and ownership](references/state-and-ownership.md)
2. **Components consume projections** from `ui/src/lib/reactive/` (one per owner and scope, never a second store) and `useApplication()` for the application context. Add a thin adapter only with its first production caller; subscribe to ordered events directly.
3. **Host tags and classes survive.** A component renders its existing `openclaw-*` tag as a plain host element in light DOM; CSS and E2E select it. Never rename a tag or a class. → [components](references/components.md)
4. **One implementation per registered tag.** Solid-rendered native hosts share their renderer through `defineSolidBridge` in `ui/src/lib/solid-bridge.ts`; use its returned component in JSX. Specialized native hosts such as Tooltip keep their existing wrapper and lifecycle owner. → [components](references/components.md)
5. **One renderer per DOM region**, and one lifecycle owner per overlay surface. → [overlays](references/overlays.md)
6. **Derive, don't synchronize.** `createMemo` before `createSignal`; no copies of owner state; no defensive guards for states the owner already excludes. Prefer smaller code with fewer owners.
7. **Keep rendering controller lifecycles out.** Production Control UI rendering controllers and host-update contracts have been removed and are guarded. The [controller-to-Solid recipe](references/idioms.md#replace-rendering-controllers) explains the boundary for new integrations: plain domain owners retain authority; Solid owns presentation and lifecycle.
## Component skeleton
An illustrative component (the tag is an example): it renders its host tag, reads an owner through a projection, and derives instead of copying state.
```tsx
import { createMemo, Show } from "solid-js";
import { useApplication } from "../lib/reactive/context.ts";
import { projectAgents } from "../lib/reactive/domain-capabilities.ts";
export function AgentCount(props: { compact?: boolean }) {
const app = useApplication();
// Reads through to the synchronous owner; disposed with this component's owner.
const agents = projectAgents(app.agents);
// Never destructure props: reads must stay reactive.
const count = createMemo(() => agents.read().agentsList?.agents.length ?? 0);
return (
<openclaw-agent-count class={["agent-count", { "agent-count--compact": props.compact }]}>
<Show when={count() > 0} fallback={<span class="muted">—</span>}>
<span>{count()}</span>
</Show>
</openclaw-agent-count>
);
}
```
Use `jsxImportSource: "@solidjs/web"` and its JSX types, not Solid 1's `solid-js/web`.
## Traps that compile but break
- `on:x`, `oncapture:`, `attr:x`, `bool:x`, `classList`, and `use:` are compile errors on native elements in rc.18. Spreads can still hide them from the compiler; keep the lint guard. `prop:` and XML namespaces remain supported.
- Events are **camelCase** (`onClick`). Dashed custom events need the exact dash, such as `onSession-change`, or a `listen(...)` ref factory.
- Native event bindings bind once: dispatch through a stable callback that reads the current handler prop. Runtime spreads, including dynamic elements, can update handlers.
- A read right after a write sees the **old** value until `flush()`. Don't write-then-read in handlers; derive.
- Reactive reads after the first `await` in an async memo are untracked, and async memos get no `AbortSignal`.
- Ref callbacks run **unowned**: `onCleanup` inside them does nothing.
- ARIA enumerations are typed strings: `aria-pressed={pressed() ? "true" : "false"}`, never a boolean.
- Solid 1 APIs (`createResource`, `onMount`, `mergeProps`, `Context.Provider`) don't carry over: use async computations, `onSettled`, `merge`, and the context component itself.
- Writing a signal or store from a memo, an effect compute phase, or a component body throws in dev. `untrack` doesn't exempt it (the guard checks the owner); derive instead, or write from a handler, `onSettled`, or effect apply.
- Class strings built with template literals or `.filter(Boolean).join(" ")` lose composable reactivity: use `class={["base", { active: active() }]}`.
- `createRenderEffect` is for render-phase runtime bindings, and `flush()` in production code usually hides a write-then-read: feature code uses `createEffect` and derivations.
## Enforced wave-zero guard
`pnpm check:control-ui-controllers` runs in lint and the changed-file checks.
For production `ui/src` and the bundled Workboard, Memory Core, Nostr, WhatsApp,
ClawRouter, and X view directories, it rejects `createRenderEffect` outside `lib/reactive/`,
all direct `addEventListener` calls in TSX, DOM queries outside the explicit
foreign-DOM owner list, and option-free memos whose callback only returns a
literal. Property/equality, async, and option-bearing memos retain their contracts.
Tests and test helpers are excluded. The native AST scan counts generic and
optional calls; `flush`, `getOwner`, and `runWithOwner` resolve actual Solid imports,
including aliases and namespaces, without counting owner methods or shadowed locals.
`createEffect`, `untrack`, `addEventListener`, `querySelector(All)`, `flush`,
`getOwner`, and `runWithOwner` also have
per-file shrink-only baselines in `config/control-ui-*-baseline.txt` and
`config/plugin-ui-*-baseline.txt`. New calls cannot borrow another file's
allowance, including allowances in another plugin or the host. Deleting
calls requires `pnpm check:control-ui-controllers --prune`; moving an allowance
requires a verified Git rename. Never raise a baseline to admit new debt. See
the [refactor checklist](references/refactor-checklist.md) for replacements and
the permitted survivors.
The guard also bans JSX `classList` and hand-written `createComponent` outside
the explicit context-adapter allowlist. Component/view `onCleanup` and manual
stored/chained import loaders have shrink-only baselines; computation cleanup
and reactive primitives remain allowed. Saving flags require recipe review:
trace the co-written `createOptimistic(false)` rather than infer busy state
from `isPending` or a nearby optimistic declaration.
More, each with its root cause: [lessons learned](references/lessons.md).
## Testing
`mountSolid`, `waitForSolid`/`flush`, `renderSolidRef`, and the Solid application-context provider live in `ui/src/test-helpers/`. `.test.tsx` files are discovered. Keep assertions when you replace a harness. Visual changes need inspected, sanitized before/after screenshots. Follow the assigned campaign's compute budget. → [testing](references/testing.md)
## References
| Topic | Read when |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [idioms](references/idioms.md) | choosing a primitive, derivations, props, lifecycle, stores, keys, async, context, diagnostics |
| [async and actions](references/async-and-actions.md) | Gateway-owned reads, optimistic mutations, keyed projections, lazy code, sibling loading |
| [refactor checklist](references/refactor-checklist.md) | refactoring or reviewing existing Solid: measurable smells, replacements, before/after |
| [components](references/components.md) | writing components, native custom-element hosts, JSX bindings, events, refs, styles |
| [state and ownership](references/state-and-ownership.md) | touching owners, projections, async reads, lifetimes, parking, chat render lifecycle |
| [overlays](references/overlays.md) | menus, popovers, tooltips, dialogs, focus, positioning, the platform floor |
| [testing](references/testing.md) | unit, browser, E2E, WebKit, parity, retention suites |
| [performance](references/performance.md) | startup bundle, lazy loading, render budgets |
| [plugins](references/plugins.md) | building a plugin's Control UI view in Solid |
| [lessons learned](references/lessons.md) | before a new kind of change; most entries cost a failed CI run to learn |From openclaw/openclaw, MIT.
More from openclaw/openclaw
- 0.767score
openclaw-live-updater
openclaw
Maintain the canonical live OpenClaw main checkout, macOS LaunchAgent-managed Gateway, local macOS app, exact-head main CI, and recurring full release…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.766score
feishu-doc
openclaw
Feishu document read/write workflows.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
slack-e2e
openclaw
Test Slack with Convex-leased user OAuth or QA bots; check credentials, exercise owned messages, prove Gateway behavior, and distinguish API evidence from…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
openclaw-release-validation
openclaw
Guide human release testing on an isolated OCM copy or approved in-place gateway, collect feedback, or refresh the release campaign.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
auto-qa
openclaw
Run OpenClaw-wide autonomous QA and live/stress campaigns across independent subsystem lanes, with verified fixes and a resumable evidence report.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
plugin-sdk-impact
openclaw
Count Plugin SDK consumers across live ClawHub releases and bundled OpenClaw plugins before deprecation, removal, or behavior changes; supports public…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
discord-e2e
openclaw
Test Discord with Convex-leased QA bots: check credentials without a Gateway, exercise owned messages, or prove OpenClaw replies, files, threads, reactions…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
proof-video
openclaw
Capture and annotate PR screenshots and videos with measured arrows, outlines, alignment guides, spacing brackets, captions, zoom, and speed cues.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
claw-score
openclaw
Audit or refresh OpenClaw maturity scorecard docs from root taxonomy, maturity scores, and QA evidence artifacts without using maintainer discrawl data or…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
openclaw-pr-maintainer
openclaw
Review, triage, repair, or land OpenClaw issues and pull requests with current-source evidence and the native maintainer workflow.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
prototype-openclaw-tui
openclaw
Build throwaway, fixture-driven OpenClaw Clack or Pi TUI prototypes and compare multiple interactive variants side by side in tmux without running the full…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
control-ui
openclaw
Operate and troubleshoot the OpenClaw Control UI: navigate connected clients, organize sessions, build session dashboards, and handle direct or…
SkillAFreshness: A★ 392.9KClaude Code +9
Signals
- Stars
- 392,925
- Forks
- 82,585
- Open issues
- 4,992
- Last commit (this folder)
- Oct 24, 2026 (4 days ago)
- Last release
- Oct 24, 2026 (4 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/openclaw/openclaw
- Website
- openclaw.ai
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from openclaw
- 0.767score
openclaw-live-updater
openclaw
Maintain the canonical live OpenClaw main checkout, macOS LaunchAgent-managed Gateway, local macOS app, exact-head main CI, and recurring full release…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.766score
feishu-doc
openclaw
Feishu document read/write workflows.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
openclaw-pr-maintainer
openclaw
Review, triage, repair, or land OpenClaw issues and pull requests with current-source evidence and the native maintainer workflow.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
auto-qa
openclaw
Run OpenClaw-wide autonomous QA and live/stress campaigns across independent subsystem lanes, with verified fixes and a resumable evidence report.
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
claw-score
openclaw
Audit or refresh OpenClaw maturity scorecard docs from root taxonomy, maturity scores, and QA evidence artifacts without using maintainer discrawl data or…
SkillAFreshness: A★ 392.9KClaude Code +9 - 0.764score
discord-e2e
openclaw
Test Discord with Convex-leased QA bots: check credentials without a Gateway, exercise owned messages, or prove OpenClaw replies, files, threads, reactions…
SkillAFreshness: A★ 392.9KClaude Code +9
Cite this page
solid skill. Agent Mart. https://agentmart.dev/skills/openclaw-solid (last updated 2026-10-24)