agentleFS
jbouderjbouder/skills/frontend-conventions/SKILL.md

frontend-conventions

Skill1 starsChanged 25 days agoMITView on GitHub

OpenTeams frontend conventions for React + TypeScript + Vite + shadcn/ui + Tailwind v4 projects. Use when writing, modifying, or reviewing frontend code — components, pages, hooks, state, data fetching, styling, or tests — in any project with a components.json or vite.config. Covers folder structure, component/test patterns, TanStack Query + Jotai, styling with semantic tokens + cn(), and Biome + Vitest quality gates.

8 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

4 rules. 0 are common, 3 are distinctive, and 1 is very specific to this project.

  • 0

    Common

    Most of the 6 edited versions we read keep these.

  • 3

    Distinctive

    This author's own choices. Worth a look.

  • 1

    Very specific

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

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Before writing code, confirm what the project actually uses — conventions below are the org default, but a given repo may differ.

    line 27
  2. Distinctive:

    Server state lives in TanStack Query, not Jotai: Never copy API data into an atom.

    line 40
  3. Very specific:

    No any: Use real types or unknown + narrowing.

    line 41
  4. Distinctive:

    Read the relevant reference before doing that kind of work — they contain the canonical code patterns:

    line 92

“Common” is measured: kept by at least 6 in 10 of the 6 edited versions of this file we could read. “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

OpenTeams Frontend Development

Conventions and patterns for the OpenTeams frontend stack. Follow these when building or changing any React frontend in this org. To scaffold a brand-new project, use the new-project skill instead — this skill governs ongoing development.

The Stack

LayerChoice
FrameworkReact 19 + TypeScript + Vite
StylingTailwind CSS v4 (CSS-first) + shadcn/ui
Iconslucide-react
RoutingReact Router v6
Server stateTanStack Query v5
Client stateJotai v2
TestsVitest + Testing Library
QualityBiome (format + lint + import sort)
Package managernpm
Dev port5173

First Moves In Any Project

Before writing code, confirm what the project actually uses — conventions below are the org default, but a given repo may differ. Check, in order:

  1. package.json — scripts, deps, package manager, React/Router/Tailwind versions.
  2. biome.json — formatter + lint settings. If absent, the repo may still be on ESLint (older projects); match what's there, don't force a migration unasked.
  3. components.json — shadcn style, baseColor, aliases, icon library.
  4. vite.config.ts — @tailwindcss/vite plugin ⇒ Tailwind v4; tailwind.config.ts + postcss ⇒ Tailwind v3.
  5. src/index.css / globals.css — color tokens and theme.
  6. The existing folder layout — mirror it. Match the surrounding code's idioms over these defaults when they conflict.

Non-Negotiables

  • Semantic color tokens only. bg-background text-foreground, never bg-white text-gray-900. This is what makes dark mode work.
  • Never hand-edit src/components/ui/. Those are shadcn-generated. Add via npx shadcn@latest add <component>. To customize, wrap or extend — don't edit in place.
  • Server state lives in TanStack Query, not Jotai. Never copy API data into an atom.
  • No any. Use real types or unknown + narrowing.
  • Co-locate tests next to the code (Foo.tsx ⇄ Foo.test.tsx).
  • Run the quality gate before declaring done: npm run build && npm run test -- --run && npm run check (Biome check = format + lint + import-organize).

Folder Structure

Components and pages each get a PascalCase directory with a barrel index.ts. Import from the folder, never the inner file.

src/
├── main.tsx
├── App.tsx
├── index.css            # Tailwind v4 entry + @theme tokens
├── lib/
│   ├── utils.ts         # cn()
│   └── api.ts           # fetch wrapper
├── store/               # all Jotai atoms
│   └── appAtoms.ts
├── hooks/               # useThing.ts — TanStack Query wrappers + custom hooks
├── components/
│   ├── ui/              # shadcn (generated — don't edit)
│   └── UserCard/
│       ├── UserCard.tsx
│       ├── UserCard.test.tsx
│       └── index.ts
├── pages/
│   └── Home/
│       ├── Home.tsx
│       ├── Home.test.tsx
│       └── index.ts
└── providers/
    └── ThemeProvider/
import UserCard from "@/components/UserCard";   // ✅ from the folder
import UserCard from "@/components/UserCard/UserCard";  // ❌ inner file

Naming

ThingConventionExample
Component / its directoryPascalCaseUserCard, UserCard/
Component filePascalCaseUserCard.tsx
Non-component filecamelCaseutils.ts, appAtoms.ts
Hook / its fileuse + camelCaseuseCurrentUser, useProducts.ts
Utility / functioncamelCaseformatDate, cn

Reference Files

Read the relevant reference before doing that kind of work — they contain the canonical code patterns:

  • references/styling.md — Tailwind v4 setup, semantic tokens, cn(), CVA component variants, dark mode, adding shadcn components.
  • references/state-and-data.md — TanStack Query hook patterns, Jotai atoms, the server-vs-client-state decision table, the api.ts wrapper.
  • references/components-and-testing.md — component file template, the barrel pattern, Vitest + Testing Library patterns (Router/Query wrappers), what to test.
  • references/quality.md — Biome config + commands, the quality-gate workflow, TypeScript strictness, common Biome rule fixes.

What NOT To Do

Don'tDo instead
Hand-edit src/components/ui/npx shadcn@latest add <component>; wrap to customize
Build a custom primitive that shadcn already shipsCheck src/components/ui/ first, then add it
Use raw Tailwind colors (bg-white, text-gray-900)Semantic tokens (bg-background, text-foreground)
Fetch in a component with useEffectA use* hook wrapping useQuery/useMutation
Store server/API data in a Jotai atomTanStack Query owns server state
Scatter atoms across component filesAll atoms in src/store/
Use anyReal types or unknown + narrowing
Flat component fileOwn PascalCase dir with test + index.ts
Reach for ESLint/Prettier configsBiome does format + lint + import sort

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.