agentleFS
VercelKnown publishervercel-labs/ui/.agents/skills/ui-sdk-write-code/SKILL.md

ui-sdk-write-code

Skill4.8k starsChanged 17 days agoApache-2.0View on GitHub

Writes and edits ui-sdk code (core, the React, Vue, Svelte, Solid and web component adapters, examples, specs and scripts) the way an expert in that framework would, then checks it with the linters, the framework expert's checklist and a cold read. Use whenever you write or change code in this repo, before you call the change done.

The file

We split this skill into the rules it gives an agent

6 rules. About 0 are common, 3 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every piece of code here has a twin that already does it well.

    line 14
  2. Distinctive:

    If two twins disagree, the shape is wrong in one of them.

    line 26
  3. Very specific:

    Read the expert's knowledge file for every framework you touch: .agents/experts/<framework>/knowledge.md, part 1 and "Common mistakes to …

    line 32
  4. Distinctive:

    Run each and check the exit code, not the output:

    line 54
  5. Very specific:

    Read the whole diff as the framework's expert would, using the "Review checklist" in each knowledge.md you loaded, and as a teammate who …

    line 69
  6. Very specific:

    Run ui-sdk-unslop on your diff.

    line 79

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Write ui-sdk code

The bar: an expert in the framework reads the file and says "this is how I'd write it", and anyone else reads it top to bottom without stopping. Readable first, then fast, never clever.

1. Find the twin

Every piece of code here has a twin that already does it well. Open it before you write a line, and copy its shape, names and order.

You're writingStart from
A core componentpackages/core/src/components/tabs/tabs.ts, or menu/ once it passes about 400 lines (menu.ts, menu-api.ts, menu-parts.ts)
A popuppackages/core/src/components/popover/popover.ts and its adapters, on createPopup in foundation/popups/
A React, Vue or Solid partThe same component's file in packages/<framework>/src/, on createParts
A Svelte partpackages/svelte/src/tabs/
A web componentpackages/web/src/tabs.ts, on createParts
An exampleThe same example in another framework: examples/components/<name>/<framework>/
A spectests/specs/tabs*.spec.ts

If two twins disagree, the shape is wrong in one of them. Say so instead of picking one.

Copy a twin's shape, not its comments. Older files carry more comments than the rules below allow.

2. Load the framework

Read the expert's knowledge file for every framework you touch: .agents/experts/<framework>/knowledge.md, part 1 and "Common mistakes to flag", and its decisions.md. It's pinned to the versions this repo installs, so trust it over memory. Write in the current idiom of that version:

  • React 19: pure render, no forwardRef, ref as a prop, no effect where an event handler or a derived value belongs, code the React Compiler compiles without a bailout.
  • Vue 3.5: <script setup lang="ts">, v-model on parts, defineModel when a component you write takes one, typed defineProps and defineSlots, no options API.
  • Svelte 5: runes only ($state, $derived, $props, $bindable), snippets, onclick attributes, attachments. No $:, on:, <slot> or createEventDispatcher. Props typed with an interface Props. Outside packages/svelte, declaration tags ({const x = $derived(...)}) instead of {@const}.
  • Solid 2: props read where they're used, never destructured; derive with memos, not effects; Solid 2 APIs only.
  • Web components: platform first. Options reflect as attributes the way built-ins do, public events are composed and don't bubble (listen with { capture: true }), and the user's markup stays in light DOM.

3. Write it

The rules in contributing/code.md hold everywhere. The ones that make code look generated when missed:

  • One shape. <Name> root, <Name><Part> per slot, render to change the element, never as. Same names and the same props in every framework.
  • Names in full words that say what a thing is. Booleans read as questions.
  • Exports listed once at the end. Inline types. No return type annotations.
  • No comment by default. Write one only when a reader would get the code wrong without it: a browser bug, an APG rule, a trade-off. One to three lines. Never a comment per declaration, and never one that explains the design or the data flow. Examples have none.
  • No defensive code for cases that can't happen. Types already rule them out.
  • No helper for one caller, and no wrapper that only renames.
  • Behavior lives in core. An adapter that grows a listener, a focus call or an aria-* attribute is in the wrong layer.

4. Check it

Run each and check the exit code, not the output:

pnpm lint
pnpm format
pnpm typecheck
pnpm --filter <package> test
pnpm --filter examples build   # when you touched examples
pnpm test:pr                   # the specs your change reaches

Then run each framework's own lint rules on the files you touched: npx eslint <files> (pnpm lint:idioms runs them on the whole repo, as CI does). Fix what each one reports and run it again until all pass. Older errors are listed in eslint-suppressions.json; when you fix one, run pnpm lint:idioms --prune-suppressions.

5. Read it cold

Read the whole diff as the framework's expert would, using the "Review checklist" in each knowledge.md you loaded, and as a teammate who has never seen it:

  • Would an expert in this framework write it this way? If you can name a more idiomatic version, write that one.
  • Is every name clear without its comment?
  • Is anything duplicated that exists elsewhere?
  • Does any function do two things, or any file hold two ideas?
  • Any allocation on a hot path, or a layout read after a write?

6. Unslop

Run ui-sdk-unslop on your diff. The change isn't done until it has. Before merging a change to an adapter, core, the specs, examples or framework docs, run ui-sdk-expert-review.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.