Agent skill

Frontend Code Style

by mailtrap in mailtrap/mailtrap-local

A skill your agent uses when writing or refactoring React + Tailwind v4 code in this repo.

MITAuto-check passedFrontend & Design

Install Frontend Code Style

skills CLI
$ npx skills add mailtrap/mailtrap-local --skill frontend-code-style -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install mailtrap/mailtrap-local frontend-code-style --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/mailtrap/mailtrap-local.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/frontend-code-style .claude/skills/frontend-code-style && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
frontend-code-style
GitHub stars
106
Token cost
~2.7k tokens
SKILL.md length
1,152 words
Files
1
Skills in repo
1
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when writing or refactoring React + Tailwind v4 code in this repo.

  • Works in 6 steps: Audit by size: find src -name '*.tsx' |… → Read the giant before touching it.… → Move CSS with the JSX it styles. Each… → …
  • Refactoring React + Tailwind v4 code in this repo
  • SKILL.md covers Overview, Directory Layout, CSS Conventions and State Patterns, plus 6 more sections
  • Calls npm

What it does

Frontend Code Style is an agent skill from mailtrap/mailtrap-local. Use when writing or refactoring React + Tailwind v4 code in this repo. Covers component sizing, CSS deduplication via primitives + shared constants, design tokens via @theme, the "adjust state during render" pattern over setState-in-effect, directory layout (ui/message/sidebar/connections), and what NOT to extract.

Its SKILL.md is about 2.7k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering Design tokens, Data cleaning and CSS and styling. It works with Tailwind CSS and React. The repository describes itself as: Local email sandbox + catcher for individual developers — single binary, SMTP + Web UI + JSON API, MIT. The licence is MIT.

When your agent uses it

  • Refactoring React + Tailwind v4 code in this repo
  • Tasks that involve Design tokens
  • Tasks that involve Data cleaning

Example prompts

  • “adjust state during render”
  • “/frontend-code-style”

Workflow steps

6 steps, taken from the first numbered list in SKILL.md.

  1. Audit by size: find src -name '*.tsx' | xargs wc -l | sort -rn | head -10. Tackle the biggest first.
  2. Read the giant before touching it. Identify natural seams (sub-components already declared inline, state used by only one branch).
  3. Move CSS with the JSX it styles. Each extracted file carries its own className constants.
  4. Tests query by role/text/title/placeholder, not className — extractions are safer than they look. Verify by reading the test file once…
  5. Update vi.mock() and vi.importActual() paths when test files move — sed for from '...' won't catch them.
  6. Run npm test and npm run build after each major extraction, not at the end.

What it can do on your machine

Read from SKILL.md and the folder at commit 92798cb. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md. Its commands use npm, which can reach the network depending on how they are called.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Frontend Code Style loads about 2.7k tokens when it runs. Until then it costs about 84 tokens; SKILL.md has 1,152 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~84
When it runs · the whole SKILL.md, loaded when a task matches
~2.7k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from mailtrap/mailtrap-local at commit 92798cb, republished under its MIT licence (© mailtrap). 1,152 words, ~2,741 tokens.

Download SKILL.mdSave it as .claude/skills/frontend-code-style/SKILL.md (or your agent's skills folder).
name
frontend-code-style
description
Use when writing or refactoring React + Tailwind v4 code in this repo. Covers component sizing, CSS deduplication via primitives + shared constants, design tokens via @theme, the "adjust state during render" pattern over setState-in-effect, directory layout (ui/message/sidebar/connections), and what NOT to extract.

Frontend Code Style

Overview

The frontend is React 19 + Tailwind v4 + Radix + Vite. Visual styling flows from @theme tokens in index.css; structure flows from a feature-folder layout under components/. This skill codifies the conventions so new code lands consistent without inventing parallel systems.

Core principle: Extract when the same shape appears 2+ times OR when one file mixes 3+ unrelated concerns. Otherwise keep classNames inline next to the JSX they style.

Directory Layout

src/
├── api/                       backend API clients
├── hooks/                     cross-cutting React hooks (incl. ConnectionProviders)
├── lib/                       pure helpers (formatters, styles constants, openInNewTab)
├── pages/                     top-level routes — MessageView, Sandbox
└── components/
    ├── ui/                    cross-cutting primitives (Button, IconButton,
    │                          Panel, Strip, EmptyCard, CategoryBadge, Toggle, icons)
    ├── message/               right-pane (MessageHeader, MessagePreview,
    │                          MessageTabs, HtmlSource, TechInfo, CodePane,
    │                          HtmlCheck/)
    ├── sidebar/               left-pane (Sidebar, SidebarToolbar, MessageList,
    │                          DeleteAllPrompt, ConnectionErrorBanner)
    ├── connections/           cloud/relay/webhook dialogs + dialogAtoms,
    │                          dialogStyles, lockedFields, SettingsMenu
    └── CodeSamples/           Sandbox empty-state code samples

Rules:

  • A component used by only one feature belongs in that feature folder, not in ui/.
  • ui/ is for primitives reused by 2+ features.
  • A component that hits 400+ lines or has clear inner sub-components becomes a folder with index.tsx (see HtmlCheck/).
  • Tests sit next to the file they test (Sidebar.test.tsx next to Sidebar.tsx).

CSS Conventions

Tokens come first

Colors, fonts, accent levels live in @theme in index.css. Use them as Tailwind utilities (bg-surface-base, text-fg-muted, text-warning, font-mono). Never hard-code hex in components — add a --color-<name> token instead.

Tailwind first, constants when reused

Single-use className: write inline.

Multi-line className constant: extract a local const xCss = [...].join(' ') next to where it's used. Use this when a className gets wide enough to wrap, or has stateful data-[…]: variants worth naming.

Cross-component reuse: extract a primitive component (preferred) or a shared constant in lib/styles.ts (when callers need to extend with their own utilities).

tsx
// ❌ Don't: invent a one-off CSS constant for a single use
const wrapperCss = 'm-0'
return <section className={wrapperCss}>…</section>

// ✅ Do: inline when used once
return <section className="m-0">…</section>

// ✅ Do: name when wide + stateful
const row = [
  'group grid grid-cols-[1fr_auto] gap-x-3 px-4 py-3',
  'data-[read=true]:bg-surface-base',
  'data-[active=true]:!bg-accent data-[active=true]:hover:!bg-accent',
].join(' ')
Variants via data-* attributes

Project convention is data-[variant=primary]:bg-accent style, not clsx/cva. See Button.tsx, IconButton.tsx, dialogStyles.btn. Match this pattern when adding new variant-driven components.

Shared structural constants (lib/styles.ts)

Use a constant (not a component) when the same CSS fragment appears across different elements (<input>, <select>, <textarea>, <pre>) and callers extend with their own utilities:

  • inputBase — border + bg + focus ring + placeholder color for form inputs.
  • codeBlockBase — min-height + mono + rounded border for code panes.

Callers compose: className={`${inputBase} px-3 py-2 text-[13px]`}.

Primitive components for repeated visual patterns

Use a component when the wrapper element itself is the abstraction:

PrimitivePurpose
<Panel>Bordered card with raised bg (TechInfo sections, HtmlCheck issue cards, EmptyCard)
<Strip variant shape>Dismissable success/error banner (card for MessageView, banner for Sidebar)
<EmptyCard>Centered muted text inside a Panel (HtmlCheck empty states)
<CategoryBadge size>Rounded category pill (header lg, list-row sm with active-state override)
<Button variant size>Pill button outside dialogs; dialogs still use dialogStyles.btn for now
<IconButton variant>28×28 / 32×32 icon buttons (toolbar, header, device)
<CodePane><pre> with mono code styling + optional pop-out
<TabRoot> <TabList> <Tab> <TabPanel>Radix Tabs wrapper that absorbs trigger/content styling

State Patterns

"Adjust state during render" over setState-in-effect

When state needs to reset on a prop/data change, do it during render with a "last-seen" tracker, not in useEffect. This is the React docs' recommended pattern; it avoids the cascading-render warning the linter flags.

tsx
// ❌ Don't
useEffect(() => {
  if (id) setMsg(null)
}, [id])

// ✅ Do
const [lastId, setLastId] = useState(id)
if (id !== lastId) {
  setLastId(id)
  setMsg(null)
}

Use useEffect only for true side effects: data fetching with cleanup, event listeners, subscriptions. setState inside an .then() / .finally() async callback is fine — the lint rule only flags the synchronous effect body.

Reset state by remounting with key

When a child owns state that needs to reset on parent prop change, use <Child key={id} /> instead of plumbing a reset callback. See <MessageHeader key={msg.id} /> in MessageView.

Hoist state only to the level that needs it

Per-issue showAll belongs inside IssueCard, not at the parent as Record<number, boolean>. Per-message device belongs inside MessagePreview, not at the page. If only one component reads the state, it should live there.

Components

Sizing
  • Page components (under pages/): orchestration + data fetching + composition. Aim for < 350 lines.
  • Feature components: < 250 lines. If a feature component grows internal sub-components, split into a folder.
  • Primitives in ui/: tiny, single concern, < 100 lines.
Extraction triggers

Split a component when any of these fire:

  • File exceeds ~400 lines.
  • Same JSX shape (an issue card, a banner) appears 2+ times across files.
  • One component carries state that only one child uses.
  • Three or more visually distinct "sections" share the file (header, list, footer all in one big return).
What NOT to extract
  • One-off className constants — keep them inline.
  • A wrapper that only renames a <div> with no logic and no shared styling — inline the <div>.
  • A helper that's a thin pass-through to a library API (e.g. a TabRoot that does nothing beyond <Tabs.Root />) — only worth it if siblings (Tab/TabPanel) need styling.
  • Premature variant props for hypothetical future use cases.
Show full SKILL.md (447 more words)Show less

Dialog Conventions

The three connection dialogs (Cloud/Relay/Webhook) share infrastructure in components/connections/:

  • dialogStyles.ts — class constants (overlay, content, field, fieldInput, btn).
  • dialogAtoms.tsx — composite components (ConnectionDialogShell, DialogField, DialogActions, DialogButton, DialogStatusRow, DialogConfigBanner).
  • lockedFields.ts — lockedFields(state?.locked, defaults) returns { isLocked, allLocked, anyLocked, inputClass, selectClass }. Use it instead of re-implementing the Record<K, boolean> boilerplate per dialog.
  • LockedFieldHint.tsx — the "pinned by config" caption under a locked input.
  • extractApiError(e) from api/client for ALL caught errors (save, disconnect, test). Never e instanceof Error ? e.message : String(e).

Workflow for Large Refactors

  1. Audit by size: find src -name '*.tsx' | xargs wc -l | sort -rn | head -10. Tackle the biggest first.
  2. Read the giant before touching it. Identify natural seams (sub-components already declared inline, state used by only one branch).
  3. Move CSS with the JSX it styles. Each extracted file carries its own className constants.
  4. Tests query by role/text/title/placeholder, not className — extractions are safer than they look. Verify by reading the test file once before extracting.
  5. Update vi.mock() and vi.importActual() paths when test files move — sed for from '...' won't catch them.
  6. Run npm test and npm run build after each major extraction, not at the end.

Anti-patterns

  • ❌ const xCss = '…' for a className used once.
  • ❌ Comments narrating what Tailwind utilities do (// rounded card with border). The class names already say that.
  • ❌ Hard-coded hex (#f5a524, #4d5a6a) — add a --color-<name> token.
  • ❌ font-['SF_Mono',Menlo,Consolas,monospace] inline — use font-mono (the --font-mono token is defined).
  • ❌ setState-in-effect for state that depends on a prop change. Use the "adjust during render" pattern.
  • ❌ <section> when there's no heading inside. Use <div> or <Panel>.
  • ❌ Re-implementing isLocked / allLocked / anyLocked per dialog. Use lockedFields().
  • ❌ e instanceof Error ? e.message : String(e) for caught API errors. Use extractApiError(e).
  • ❌ Smart quotes anywhere. ASCII only.

Common Mistakes

SymptomLikely causeFix
"Cannot find name 'X'" after a moveTest file's vi.mock('../api/X') still uses old pathBump ../ to ../../ to match the SUT's import depth
Tab won't switch when clicked from outside the TabListTabRoot not wired controlled (value + onValueChange both needed)Ensure both props are passed
className wins/loses by source orderTailwind v4 sorts variants alphabetically, not source-orderUse ! to force precedence on the data-attr that should win (see MessageRow's active vs read)
setState in effect warningEffect is being used for state sync, not side effectMove to "adjust state during render" pattern with a lastX tracker
Imports break after moving file into a deeper folderRelative paths to api//lib//hooks/ need one extra ../Bump each ../{api,hooks,lib,assets,test}/ → ../../$1/

Validation note

This skill captures patterns from a recent refactoring pass and has not been pressure-tested with subagents per the writing-skills TDD methodology. Future work: write baseline scenarios (e.g. "add a new connection dialog", "extract a new tab from MessageView") and verify agents apply these conventions without prompting.

© mailtrap, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/frontend-code-style of mailtrap/mailtrap-local.

Open the folder on GitHubat commit 92798cb

Compare with similar skills

Frontend Code Style next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Frontend Code Style compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Frontend Code Style this skillmailtrap/mailtrap-local106—~2.7kAutomated safety check: PassMIT
Extract DesignManavarya09/design-extract4.2k—~786Automated safety check: NotesMIT
Frontend UI FunctionalvictorGPT/vibeusage131—~939Automated safety check: PassMIT
Tailwind V4 Shadcnever-works/ever-works1582 repos~3.8kAutomated safety check: PassMIT
Frontend UI Foundryjiushiwon/wg-skills110—~1.4kAutomated safety check: PassApache-2.0
Shadcn Tailwind UILiarMTTT/TavernWeave148—~1.7kAutomated safety check: PassCustom licence

Similar skills

  • Extract Design

    Manavarya09/design-extract

    Extract the full design language from any website URL. An agent skill from Manavarya09/design-extract.

    4.2k GitHub stars~786 tokensUpdated 8 days ago
    Frontend & DesignAuto-check: notes
  • Frontend UI Functional

    victorGPT/vibeusage

    A skill your agent uses when building or refactoring functional React/Vite/Tailwind UI pages, templates, or component libraries that need consistent structure, tokenized styling, accessibility…

    131 GitHub stars~939 tokensUpdated 2 mo ago
    Frontend & DesignAuto-check passed
  • Tailwind V4 Shadcn

    ever-works/ever-works

    Production-tested setup for Tailwind CSS v4 with shadcn/ui, Vite, and React.

    158 GitHub starsUsed in 2 repos~3.8k tokens
    Frontend & DesignAuto-check passed
  • Frontend UI Foundry

    jiushiwon/wg-skills

    A skill your agent uses when generating UI for a specific scenario (mobile/PC/官网/管理端/营销页/文档/金融/原生/3D), when refactoring an existing HTML/Vue/React project to a unified design system, when extracting…

    110 GitHub stars~1.4k tokensUpdated 3 days ago
    Frontend & DesignAuto-check passed
  • Shadcn Tailwind UI

    LiarMTTT/TavernWeave

    Build, restyle, or review accessible React interfaces that use shadcn/ui, Radix UI primitives, and Tailwind CSS.

    148 GitHub stars~1.7k tokensUpdated 3 days ago
    Frontend & DesignAuto-check passed
  • Shift UI Components

    shift-editor/shift

    Guides design, implementation and review of Shift interface work: shared Base UI wrappers, Tailwind v4 theme tokens, Figma matching and accessible interaction states.

    343 GitHub stars~2.5k tokensUpdated yesterday
    Frontend & DesignAuto-check passed

Questions about Frontend Code Style

What does Frontend Code Style do?

A skill your agent uses when writing or refactoring React + Tailwind v4 code in this repo. Frontend Code Style is an agent skill from mailtrap/mailtrap-local. Use when writing or refactoring React + Tailwind v4 code in this repo.

When should I use Frontend Code Style?

Frontend Code Style fits situations like: refactoring React + Tailwind v4 code in this repo; tasks that involve Design tokens; tasks that involve Data cleaning.

How do I install Frontend Code Style in Claude Code?

Run `npx skills add mailtrap/mailtrap-local --skill frontend-code-style -a claude-code`. Or copy the skill folder (.claude/skills/frontend-code-style in mailtrap/mailtrap-local) into .claude/skills/frontend-code-style in your project. Claude Code loads it when a task matches its description.

How do I install Frontend Code Style in Codex?

Run `npx skills add mailtrap/mailtrap-local --skill frontend-code-style -a codex`. Or copy the skill folder (.claude/skills/frontend-code-style in mailtrap/mailtrap-local) into .agents/skills/frontend-code-style in your project. Codex loads it when a task matches its description.

Can I use Frontend Code Style in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mailtrap/mailtrap-local --skill frontend-code-style -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/frontend-code-style, .gemini/skills/frontend-code-style, .github/skills/frontend-code-style and .opencode/skills/frontend-code-style in your project.

What does Frontend Code Style need to run?

Going by SKILL.md and its folder, Frontend Code Style needs the command-line tools its instructions call (npm).

Does Frontend Code Style access the network?

SKILL.md contains no URLs. Its commands use npm, which can reach the network depending on how they are called. This is read from the text; nothing was executed.

Is Frontend Code Style safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Frontend Code Style use?

Frontend Code Style is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Frontend Code Style use?

About 2.7k tokens (SKILL.md is roughly 11k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Frontend Code Style?

Skills that share tags, products or a category with Frontend Code Style: Extract Design (Manavarya09/design-extract, 4.2k stars), Frontend UI Functional (victorGPT/vibeusage, 131 stars), Tailwind V4 Shadcn (ever-works/ever-works, 158 stars) and Frontend UI Foundry (jiushiwon/wg-skills, 110 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Frontend Code Style?

mailtrap (a GitHub organization) maintains it in mailtrap/mailtrap-local, which has 106 GitHub stars. The repository was last updated on September 7, 2026.

Source: mailtrap/mailtrap-local on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.