skills/frontend-component/SKILL.md
Create React/Vue component with TypeScript, tests, and styles. Auto-invoke when user says "create component", "add component", "new component", or "build component".
npx skillsauth add alekspetrov/navigator frontend-componentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Generate production-ready React/Vue components with TypeScript, tests, and styles following modern best practices.
Auto-invoke when user mentions:
Before gathering requirements, query the knowledge graph for what we already know about frontend/component work in this project. This mirrors navigator-research's Phase 0 and prevents re-deriving patterns we've already decided on.
PLUGIN_DIR="${CLAUDE_PLUGIN_DIR:-$HOME/.claude/plugins/cache/navigator-marketplace/navigator}"
[ -d "$PLUGIN_DIR" ] || PLUGIN_DIR="$HOME/.claude/plugins/marketplaces/navigator-marketplace"
python3 "$PLUGIN_DIR/skills/nav-graph/functions/graph_manager.py" \
--action query --concept frontend \
--graph-path .agent/knowledge/graph.json 2>/dev/null | head -40
If memories surface (look for PATTERN, PITFALL, DECISION entries), read the full memory files for any directly relevant ones:
ls .agent/knowledge/memories/{patterns,pitfalls,decisions}/ 2>/dev/null
What to do with what you find:
pitfalls_avoided in Step 8)If the graph returns nothing useful, proceed without it. Skip this step only if the knowledge graph is disabled in .agent/.nav-config.json.
First, detect the framework: read package.json. If "next" is in dependencies, this is a Next.js App Router project — use the Next.js variants in Step 3 and default styling to Tailwind (no CSS module file). See .agent/philosophy/NEXTJS-PATTERNS.md for the patterns these templates encode.
Ask user for component details:
Component name: [PascalCase name, e.g., UserProfile]
Component type:
Generic React:
- simple (basic functional component)
- with-hooks (useState, useEffect, etc.)
- container (data fetching component)
Next.js App Router:
- nextjs-page (app/<route>/page.tsx — Server Component, async)
- nextjs-layout (app/<route>/layout.tsx — Server Component, metadata + viewport)
- nextjs-server (Server Component with fetch, async)
- nextjs-client ('use client' component with state/effects)
Styling approach:
- tailwind (default for nextjs-* types)
- css-modules (default for generic React types)
- styled-components
Props needed: [Optional: describe expected props]
Picking the right Next.js variant:
nextjs-pagenextjs-layoutuseState" / "click handler" / "interactive" → nextjs-clientnextjs-serverValidate component name:
functions/name_validator.pyIMPORTANT: This step MUST be executed for complex components.
Before generating files, confirm interpretation with user.
Display verification:
I understood you want:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Component: {NAME}
Type: {TYPE} (inferred because: {REASON})
Location: src/components/{NAME}/
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Detected patterns from your codebase:
- Styling: {CSS_APPROACH} (found {EVIDENCE})
- Testing: {TEST_LIBRARY} (found in package.json)
- Similar component: {EXISTING_COMPONENT} at {PATH}
Props I'll generate:
{PROPS_PREVIEW}
Proceed with generation? [Y/n]
Skip verification if (HIGH-STAKES ONLY mode):
Always verify if:
Based on component type and requirements:
Use predefined function: functions/props_interface_generator.py
# Generates TypeScript interface based on component requirements
python3 functions/props_interface_generator.py \
--name "UserProfile" \
--props "userId:string,onUpdate:function,isActive:boolean"
Output:
interface UserProfileProps {
userId: string;
onUpdate?: () => void;
isActive?: boolean;
children?: React.ReactNode;
className?: string;
}
Use appropriate template based on type:
Simple component:
Use template: templates/component-simple-template.tsx
Component with hooks / Container component:
Start from templates/component-simple-template.tsx and add the hook
declarations (useState/useEffect) or data-fetching logic inline — there is
no separate with-hooks/container template file; the simple template is the base.
Next.js App Router variants (use when "next" is in package.json):
| --type | Template | Output path example |
|------------------|---------------------------------------------------------|----------------------------------------|
| nextjs-page | templates/nextjs-page-template.tsx | app/schedule/page.tsx |
| nextjs-layout | templates/nextjs-layout-template.tsx | app/schedule/layout.tsx |
| nextjs-server | templates/nextjs-server-component-template.tsx | app/components/speaker-list.tsx |
| nextjs-client | templates/nextjs-client-component-template.tsx | app/components/favourite-button.tsx |
The Next.js templates already encode Next.js 15+/16 conventions:
params/searchParams are Promises — await them'use client' directive on line 1 of client components, above all importsSkip Step 5 (Style File) for nextjs-* types — Tailwind classes are baked into the templates, no CSS module needed.
Use predefined function: functions/component_generator.py
python3 functions/component_generator.py \
--name "UserProfile" \
--type "simple" \
--props-interface "UserProfileProps" \
--template "templates/component-simple-template.tsx" \
--output "src/components/UserProfile/UserProfile.tsx"
Template substitutions:
${COMPONENT_NAME} → Component name (PascalCase)${PROPS_INTERFACE} → Generated props interface${STYLE_IMPORT} → CSS module import${DESCRIPTION} → Brief component descriptionUse predefined function: functions/file_generator.py
python3 functions/file_generator.py \
--component-name "UserProfile" \
--component-path "src/components/UserProfile/UserProfile.tsx" \
--template "templates/test-template.test.tsx" \
--output "src/components/UserProfile/UserProfile.test.tsx"
Test template includes:
Template substitutions:
${COMPONENT_NAME} → Component name${IMPORT_PATH} → Relative import path${TEST_CASES} → Generated test cases based on propsUse predefined function: functions/style_generator.py
python3 functions/style_generator.py \
--name "UserProfile" \
--approach "css-modules" \
--template "templates/style-template.module.css" \
--output "src/components/UserProfile/UserProfile.module.css"
CSS Modules template:
.container {
/* Component wrapper styles */
}
.title {
/* Title styles */
}
/* Add more classes as needed */
Styled Components alternative:
// Generated if --approach "styled-components"
import styled from 'styled-components';
export const Container = styled.div`
/* Component wrapper styles */
`;
export const Title = styled.h2`
/* Title styles */
`;
Create index.ts for clean imports:
Write(
file_path: "src/components/UserProfile/index.ts",
content: "export { UserProfile } from './UserProfile';\nexport type { UserProfileProps } from './UserProfile';\n"
)
Allows usage:
import { UserProfile } from '@/components/UserProfile';
Display generated files and usage:
✅ Component Created: UserProfile
Structure:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📁 src/components/UserProfile/
├── UserProfile.tsx (Component)
├── UserProfile.test.tsx (Tests)
├── UserProfile.module.css (Styles)
└── index.ts (Exports)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Props Interface:
interface UserProfileProps {
userId: string;
onUpdate?: () => void;
isActive?: boolean;
}
Usage:
import { UserProfile } from '@/components/UserProfile';
<UserProfile
userId="123"
onUpdate={() => console.log('Updated')}
isActive={true}
/>
Next Steps:
1. Customize component implementation
2. Run tests: npm test UserProfile
3. Import and use in your feature
After Step 7, emit an execution_summary JSON block that captures patterns/decisions/pitfalls from this run. This block is the parity equivalent of the research_findings block emitted by navigator-research, and it gets ingested into the knowledge graph so future component work can surface what we learned.
Output the block verbatim (replace placeholders with actual values from this run):
{
"execution_summary": {
"skill": "frontend-component",
"task": "{COMPONENT_NAME} component",
"files_created": ["{paths of files written}"],
"files_modified": ["{paths of files edited}"],
"tests_added": ["{test file path}"],
"stack_detected": "{e.g. react+typescript+vitest}",
"patterns_followed": [
{"summary": "{convention applied — e.g. functional component with Props interface}", "concepts": ["frontend"], "confidence": 0.8}
],
"decisions_made": [
{"summary": "{non-obvious choice — e.g. React.memo because props are stable}", "concepts": ["frontend"], "confidence": 0.75, "evidence": "{path:line}"}
],
"pitfalls_avoided": [],
"assumptions_made": ["{e.g. project uses CSS Modules (detected via existing components)}"]
}
}
Ingestion (run from project root):
PLUGIN_DIR="${CLAUDE_PLUGIN_DIR:-$HOME/.claude/plugins/cache/navigator-marketplace/navigator}"
[ -d "$PLUGIN_DIR" ] || PLUGIN_DIR="$HOME/.claude/plugins/marketplaces/navigator-marketplace"
echo '<execution_summary JSON>' | python3 "$PLUGIN_DIR/skills/nav-graph/functions/execution_to_graph.py" -
Rules:
decisions_made and pitfalls_avoided entries that are non-obvious and would help future runs.Validates component naming conventions.
Usage:
python3 functions/name_validator.py --name "UserProfile"
Checks:
Returns: Valid name or error message
Generates TypeScript props interface from user input.
Usage:
python3 functions/props_interface_generator.py \
--name "UserProfile" \
--props "userId:string,onUpdate:function,isActive:boolean"
Supported types:
string, number, booleanfunction (becomes () => void)array (becomes any[])object (becomes Record<string, any>)react-node (becomes React.ReactNode)Returns: TypeScript interface string
Generates component file from template with substitutions.
Usage:
python3 functions/component_generator.py \
--name "UserProfile" \
--type "simple" \
--props-interface "UserProfileProps" \
--template "templates/component-simple-template.tsx" \
--output "src/components/UserProfile/UserProfile.tsx"
Parameters:
--name: Component name (PascalCase)--type: Component type (simple/with-hooks/container)--props-interface: Props interface name--template: Template file path--output: Output file pathReturns: Generated component code
Generates test file with React Testing Library.
Usage:
python3 functions/file_generator.py \
--component-name "UserProfile" \
--component-path "src/components/UserProfile/UserProfile.tsx" \
--template "templates/test-template.test.tsx" \
--output "src/components/UserProfile/UserProfile.test.tsx"
Generates tests for:
Returns: Generated test code
Generates style file (CSS Modules or Styled Components).
Usage:
python3 functions/style_generator.py \
--name "UserProfile" \
--approach "css-modules" \
--template "templates/style-template.module.css" \
--output "src/components/UserProfile/UserProfile.module.css"
Supported approaches:
css-modules (default)styled-componentstailwind (generates className utilities)Returns: Generated style code
Basic functional component template.
Placeholders:
${COMPONENT_NAME} - Component name${PROPS_INTERFACE} - Props interface definition${STYLE_IMPORT} - CSS import statement${DESCRIPTION} - Component descriptionComponents needing hooks or data fetching start from
component-simple-template.tsx(above) and the model adds theuseState/useEffectdeclarations or fetch logic inline — no dedicated with-hooks/container template ships.
React Testing Library test template.
Placeholders:
${COMPONENT_NAME} - Component name${IMPORT_PATH} - Import path${TEST_CASES} - Generated test casesCSS Modules template.
Placeholders:
${COMPONENT_NAME_KEBAB} - Component name in kebab-case${BASE_STYLES} - Base container stylesSee examples/ directory for reference implementations:
Each example includes:
any type (use unknown if needed)Problem: Generated component throws errors
Solutions:
Problem: Generated tests don't pass
Solutions:
--verbose flagProblem: CSS modules not loading
Solutions:
This skill succeeds when:
Auto-invoke this skill when creating React components to ensure consistency and save time ⚛️
tools
Sync project CLAUDE.md to the installed Navigator version, preserving customizations. Use when user says "sync CLAUDE.md", "update CLAUDE.md", or when detecting outdated Navigator configuration.
tools
Automates design review, token extraction, component mapping, and implementation planning. Reduces design handoff from 6-10 hours to 5 minutes via direct Figma MCP integration. Auto-invoke when user mentions design review, Figma mockup, or design handoff.
tools
Automates Navigator plugin updates. Detects current version, updates plugin, verifies installation, updates project CLAUDE.md, and validates new features. Auto-invoke when user mentions upgrading Navigator or getting new features.
documentation
Manage Navigator task documentation - create implementation plans, archive completed tasks, update task index. Use when user starts new feature, completes work, or says "document this feature".