# Pattern Implement

> Build Common Fabric patterns and sub-patterns

- Skill: `commontoolsinc/pattern-implement` (Agent Skill)
- Install (CLI): `npx skillmds@latest add commontoolsinc/pattern-implement`
- Raw SKILL.md: https://api.skillmd.com/api/skills/commontoolsinc/pattern-implement/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: commontoolsinc (https://skillmd.com/u/commontoolsinc)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/commontoolsinc/pattern-implement

---


Use the `cf` skill, or read `skills/cf/SKILL.md`, for CLI documentation when
running commands.

# Implement Pattern

## Core Rule

Match the implementation mode to the task.

For Pattern Factory Build, implement the top-level pattern deliverable described
by the brief, spec, UX design, and UI design. Use sub-patterns only when they
make the implementation clearer.

For an isolated sub-pattern task, write one sub-pattern with minimal UI first so
data flow can be verified before polish.

**Always use `pattern<Input, Output>()`** - expose actions as `Stream<T>` for
testability.

## Order

1. Leaf patterns first (no dependencies on other patterns)
2. Container patterns (compose leaf patterns)
3. main.tsx last (composes everything)

## Read First

- The reads mandated by pattern-dev:
  `docs/common/ai/pattern-development-guide.md` (especially the SES authoring
  limits and escape-hatch guidance), `docs/common/concepts/reactivity.md`,
  `docs/common/patterns/new-cells.md`, and — in a Pattern Factory Build
  workspace — `docs/common/ai/pattern-factory-build-guide.md`
- `docs/common/patterns/` - generalizable pattern idioms
- `docs/common/concepts/action.md` - action() for local state
- `docs/common/concepts/handler.md` - handler() for reusable logic
- `docs/common/concepts/identity.md` - equals() for object comparison
- `docs/common/patterns/multi-user-patterns.md` - Presenting Identity (viewer
  via `#profile`, every participant rendered with `cf-profile-badge` bound to
  their stored profile cell — `cf-avatar` + snapshot only as an offline
  fallback, roster built by join storing the live profile cell) when the pattern
  has multiple people or a current-user concept

For Pattern Factory Build, do not start implementation until you have read the
Build guide plus the two foundational reactivity/local-cell references above.

## Key Patterns

**action()** - Closes over local state in pattern body:

```tsx
const inputValue = new Writable("");
const submit = action(() => {
  items.push({ text: inputValue.get() });
  inputValue.set("");
});
```

Use `new Writable()` only for pattern-owned local cells initialized from static
values. Do not pass an input prop, mapped field, computed value, or other
reactive value into `new Writable()`. If the pattern receives writable state,
use that input cell directly; if a draft needs to copy from input state, copy in
an action or another valid reactive/event context.

For Pattern Factory Build, this rule applies to the top-level pattern input
object too. Do not initialize local state with `new Writable(input.name || "")`,
`new Writable(input.items || [])`, `new Cell(input.field)`, or helper calls
around `input.field`. First decide whether each field is primary pattern state,
static local UI state, or draft/editing state:

- Primary pattern state: expose it in the `Input`/`Output` contract with
  `Default<>` and `Writable<>` as needed, then use the reactive input directly.
- Static local UI state: create it with `new Writable(...)` from static literals
  only.
- Draft/editing state: create it from a static value, then copy from input state
  inside an `action()` or another valid event/reactive context.

Transient UI state (active tab, selected item, filter text, open modal): apply
the PerSession new-tab test from the pattern-dev skill.

When a pattern needs explicit time or randomness, call the JavaScript built-ins
directly: `Date.now()` (or `new Date()`) for the clock and `Math.random()` for
entropy. These are gated inside a pattern sandbox — allowed only inside a
handler, where the clock is coarsened to one-second resolution — and throw a
`TimeCapabilityError` in a `computed()`/`lift()` or at pattern-body level. To
read a live clock reactively in a `computed()`, use the `#now` wish instead. If
a control is already bound to a cell, usually via `$value` or `$checked`, let
that binding own the control value. Use `oncf-change` / `oncf-input` only for
dependent state or other side effects.

Do not invoke streams or writes while assigning JSX event props. For example,
`onClick={selectItem.send(index)}` runs during render; use
`onClick={() => selectItem.send(index)}` or a bound `handler()` instead. This is
especially important inside `.map()` bodies because render-time writes can make
`raw:map` non-idempotent.

**handler()** - Reused with different bindings:

```tsx
const deleteItem = handler<void, { items: Writable<Item[]>; index: number }>(
  (_, { items, index }) => items.set(items.get().toSpliced(index, 1)),
);
// In JSX: onClick={deleteItem({ items, index })}
```

**Rendering sub-patterns** - Function calls and JSX both work (verified: both
forms pass `cf check` with a typed Output interface):

```tsx
// ✅ Function call form
return <>{items.map((item) => ItemPattern({ item, allItems: items }))}</>;

// ✅ JSX form
return <>{items.map((item) => <ItemPattern item={item} />)}</>;
```

The sub-pattern's Output type must include `[UI]: VNode` — see
`docs/common/patterns/composition.md`.

## Done When

- Pattern compiles: `deno task cf check pattern.tsx --no-run`
- The top-level UI or sub-pattern UI renders the behavior needed for the task
- New behavior is structured so tests can exercise it through typed streams,
  handlers, or observable state
- Ready for testing

