Skip to content
Agentmart
Submit a tool

frontend-best-practices

Frontend engineering standards — component architecture, state, async, forms, accessibility, performance and TypeScript discipline.

Skill by O-Marsters-1997

IndexedMIT
Write a review

Chalk Labs

Need help deploying frontend-best-practices?

Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.

Book a call

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/o-marsters-1997-frontend-best-practices

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.

We use your email only for this newsletter. Privacy

About

Frontend engineering standards — component architecture, state, async, forms, accessibility, performance and TypeScript discipline. Detects the project's framework and loads only the matching guidance. TRIGGER — load BEFORE writing or editing frontend code, not after: any .tsx, .jsx, .vue, .svelte, or component/hook file is being created or edited; the prompt names a component, hook, prop, state, form, modal, route, page, React, Next, Solid, SolidStart, solid-js, signal, useState, useEffect, createSignal, createStore, createResource, createAsync, <For>, <Show>, store, context, a11y, or web vitals. Trigger on plain feature requests in a frontend repo — "add a button", "wire up this form", "make this load faster", "fix this rerender" — the user will not say "best practices"; the component file is the trigger. Load it even when another skill (tdd, impeccable, simplify) is already active. SKIP only for backend-only work with no UI file touched.

Use cases: design, frontend, backend, testing

No 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/frontend-best-practices

Tools it pre-approves 7

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Read,
  • Edit,
  • Write,
  • Glob,
  • Grep,
  • Bash,
  • Agent

What's inside

Skill name
frontend-best-practices
Description
Frontend engineering standards — component architecture, state, async, forms, accessibility, performance and TypeScript discipline. Detects the project's framework and loads only the matching guidance. TRIGGER — load BEFORE writing or editing frontend code, not after: any .tsx, .jsx, .vue, .svelte, or component/hook file is being created or edited; the prompt names a component, hook, prop, state, form, modal, route, page, React, Next, Solid, SolidStart, solid-js, signal, useState, useEffect, createSignal, createStore, createResource, createAsync, <For>, <Show>, store, context, a11y, or web vitals. Trigger on plain feature requests in a frontend repo — "add a button", "wire up this form", "make this load faster", "fix this rerender" — the user will not say "best practices"; the component file is the trigger. Load it even when another skill (tdd, impeccable, simplify) is already active. SKIP only for backend-only work with no UI file touched.
License
MIT
Allowed tools
Read,, Edit,, Write,, Glob,, Grep,, Bash,, Agent
Instructions
172 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (13)

  • SKILL.md
  • evals.json · evals/
  • TodoList.tsx · evals/fixtures/
  • UserCard.tsx · evals/fixtures/
  • UserDashboard.tsx · evals/fixtures/
  • package.react.json · evals/fixtures/
  • package.solid.json · evals/fixtures/
  • useToggleSearch.tsx · evals/fixtures/
  • react.md · references/
  • solidjs.md · references/
  • async.md · references/solidjs/
  • solid-2.md · references/solidjs/
  • stores.md · references/solidjs/

SKILL.md (first lines)

# Frontend

Best practices for building UI that is correct, accessible, fast, and type-safe. The principles
below are framework-neutral — they hold whether you write React, SolidJS, or anything else. The
framework-specific *how* lives in references that you load on demand, because the single biggest
source of frontend bugs is applying one framework's mental model to another.

## Framework Selection — do this first

The shared principles tell you *what* to aim for. They do **not** tell you how to write reactive
code, because that diverges sharply by framework and getting it wrong is the most common cause of
"my UI won't update" and "this re-renders too much" bugs. So before writing or reviewing reactive
logic, detect the framework and load exactly one reference.

Detect in this order; stop at the first signal:

1. **Explicit user statement.** If the user names the framework ("this is a Solid project"), honor it.
2. **`package.json` dependencies** — the strongest signal. In a monorepo, read the `package.json`
   nearest the file being edited, not the root one.
   - `react` / `react-dom` (or `next`) → load `references/react.md`
   - `solid-js` / `@solidjs/*` (e.g. `@solidjs/router`, `@solidjs/start`) → load `references/solidjs.md`
   - `tsconfig.json` `"jsxImportSource"` confirms it: `"solid-js"` or `"@solidjs/web"` means Solid.
3. **The working file's extension + imports.** `.tsx`/`.jsx` with `import … from "react"` or hook
   calls like `useState` → React. `import { createSignal } from "solid-js"`, or JSX that uses
   `<For>`/`<Show>` → SolidJS. (Note: both use `.tsx`, so extension alone is not decisive — read the imports.)

```bash
# Quick check:
grep -E '"(react|react-dom|next|solid-js|@solidjs/[^"]+|solid-start)"' package.json
grep -E '"jsxImportSource"' tsconfig*.json
```

Load **only** the matching reference — don't load both. A framework with no reference yet (Vue,
Svelte) gets the shared principles alone; don't ask. If React and Solid signals genuinely conflict,
or none are present (a fresh file in an empty repo), ask the user once, then proceed.

Server-rendered templates driven by `hx-*` attributes are not a component framework: in a Go
`html/template` app use the `htmx-go-templates` skill instead, including for the TS module that
backs it.

**Why this matters (the core divergence):** React re-runs the whole component function on every
render and relies on dependency arrays + memoization to *prevent* unnecessary work and re-renders.
SolidJS runs each component function *once* and uses fine-grained signals to update only the exact
DOM nodes that changed — there is no re-render to optimize away. This single difference flips the
guidance on memoization, effects, derived state, list rendering, and props. The reference re-states
each shared topic in its framework's own model — read it there, don't infer it from the principles below.

To add a framework later: drop a new `references/<framework>.md` mirroring the taxonomy headings,
and add one detection rule above. Nothing in the shared body should need to change.

---

## Shared principles

These are framework-neutral. Each maps to a same-named, same-ordered heading in every reference,
where the framework-specific mechanics live.

### 1. Component architecture & composition

Favor composition over inheritance and over configuration-by-boolean-props. A component that
sprouts `isModal`, `isCompact`, `variant` flags is usually two or three components wearing a
trenchcoat — split it. Reach for compound components (a parent coordinating related children),
render props / slots, and polymorphic `as`-style components when you need flexible composition
rather than a growing prop matrix.

Give each component a single responsibility, and a clean, fully typed prop API that describes
*what it accepts*, not *how it's implemented*. Avoid prop drilling: passing a value through
several layers that don't use it is a smell — lift the state, share it via context, or restructure
so the consumer sits closer to the source. The test: a reader should understand a component's
contract from its props alone.

### 2. State & data flow

Distinguish **server state** (data fetched from an API — it has a canonical source elsewhere,
goes stale, needs caching and revalidation) from **client/local state** (UI concerns the client
owns: open/closed, selected tab, form-in-progress). Never park fetched server data in ad-hoc local
state and hand-sync it — that's how you get stale and inconsistent UIs. Use a server-state/query
layer for the former.

Colocate state with the component that uses it, and lift it only as far as the nearest common
ancestor that needs it — no higher. Use context for genuinely shared, low-frequency state (theme,
auth, locale), not as a global dumping ground. When state transitions get complex or
interdependent, model them with a reducer / state machine so invalid states are unrepresentable.
Prefer **derived** state — computed from existing state — over storing a copy you must keep in sync.

### 3. Async & data fetching

Model every async operation as four explicit states: **loading, error, empty, and success**. The
empty state (a successful fetch that returned nothing) is the one people forget, and it's a
different UI from loading. Don't render `data.map(...)` against a maybe-undefined value.

Cache and dedupe requests so the same data isn't fetched five times across a screen. Guard against
**race conditions**: when inputs change faster than responses return (search-as-you-type), a stale
response can overwrite a fresh one — cancel or ignore out-of-order results. Use the framework's
suspense/async boundary primitives to keep loading and error handling declarative rather than
scattering `if (loading)` branches everywhere.

### 4. Forms & validation

Prefer controlled inputs so the component state is the single source of truth for field values.
Define one **schema** (Zod) and infer your TypeScript types from it rather than declaring types and
validators separately and letting them drift. Validate untrusted input at the boundary — client
validation is for UX, but never trust it for correctness or security; the server validates too.

Make errors accessible: associate each message with its field (`aria-describedby`), move focus to
the first error on failed submit, and announce validation results so screen-reader users aren't
stranded on a form that silently rejected them.

### 5. Accessibility

Reach for semantic HTML first — a real `<button>`, `<nav>`, `<label>`, `<dialog>` gives you
keyboard behavior, focus, and screen-reader semantics for free. Add ARIA only to fill genuine gaps
semantic HTML can't cover; incorrect ARIA is worse than none. Every interactive element must be
reachable and operable by keyboard, with visible focus and sensible focus management (trap focus in
modals, restore it on close). Meet WCAG 2.1 AA contrast (4.5:1 for normal text). Run automated
checks (axe, Lighthouse) as a floor — they catch maybe a third of issues, so tab through the UI
yourself too.

### 6. Performance & rendering

From O-Marsters-1997/my-claude-code, MIT.

More from O-Marsters-1997/my-claude-code

Signals

Stars
0
Forks
0
Open issues
10
Last commit (this folder)
Oct 12, 2026 (19 days ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from O-Marsters-1997

Done for you

Rather not set it up yourself?

Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.

See how we build AI agents →Read the case studies

Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.

launches shipped
50+
launches shipped
media placements
500+
media placements
founders on every account
2
founders on every account

Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block

Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.

Get frontend-best-practices running in your business

Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.

Goes to the Chalk Labs founders, not the newsletter. Privacy

Need help deploying frontend-best-practices?

CallGet help
Cite this page

frontend-best-practices skill. Agent Mart. https://agentmart.dev/skills/o-marsters-1997-frontend-best-practices (last updated 2026-10-24)