← スキル一覧に戻る

solid-react
by fusengine
Redefining development through cognitive automation and collaborative agent systems.
⭐ 0🍴 0📅 2026年1月24日
SKILL.md
name: solid-react description: SOLID principles for React 19. Files < 100 lines, hooks separated, interfaces in src/interfaces/, JSDoc mandatory. Use for React architecture and code quality. user-invocable: false
SOLID React - Component Architecture
Current Date (CRITICAL)
Today: January 2026 - ALWAYS use the current year for searches. Search with "2025" or "2026", NEVER with past years.
MANDATORY: Research Before Coding
CRITICAL: Check today's date first, then search documentation BEFORE writing any code.
- Use Context7 to query React official documentation
- Use Exa web search with current year for latest trends
- Verify package versions for React 19 compatibility
WORKFLOW:
1. Check date → 2. Research docs + web (current year) → 3. Apply latest patterns → 4. Code
Codebase Analysis (MANDATORY)
Before ANY implementation:
- Explore project structure to understand architecture
- Read existing related files to follow established patterns
- Identify naming conventions, coding style, and patterns used
Absolute Rules (MANDATORY)
1. Files < 100 lines
- Split at 90 lines - Never exceed 100
- Components < 50 lines (use composition)
- Hooks < 30 lines each
- Services < 40 lines each
2. Modular Architecture
src/
├── modules/ # ALL modules here
│ ├── cores/ # Shared (global to app)
│ │ ├── components/ # Shared UI (Button, Modal)
│ │ ├── lib/ # Utilities
│ │ └── stores/ # Global state
│ │
│ ├── auth/ # Feature module
│ │ ├── components/
│ │ └── src/
│ │ ├── interfaces/
│ │ ├── services/
│ │ ├── hooks/
│ │ └── stores/
│ │
│ └── [feature]/ # Other feature modules
│
├── routes/ # TanStack Router routes
└── main.tsx
3. JSDoc Mandatory
/**
* Fetch user by ID from API.
*
* @param id - User unique identifier
* @returns User object or null if not found
*/
export async function getUserById(id: string): Promise<User | null>
4. Interfaces Separated
modules/[feature]/src/interfaces/
├── user.interface.ts
├── post.interface.ts
└── api.interface.ts
NEVER put interfaces in component files.
SOLID Principles
S - Single Responsibility
1 component = 1 UI concern 1 hook = 1 logic concern
// ❌ BAD - Mixed concerns
function UserProfile() {
// fetching, formatting, validation, rendering...
}
// ✅ GOOD - Separated
function UserProfile({ user }: UserProfileProps) {
return <UserCard user={user} />
}
function useUser(id: string) {
// fetching logic only
}
O - Open/Closed
Components extensible without modification
// Extensible via props
interface ButtonProps {
variant?: 'primary' | 'secondary'
size?: 'sm' | 'md' | 'lg'
children: React.ReactNode
}
L - Liskov Substitution
All implementations respect contracts
interface DataSource<T> {
fetch(): Promise<T[]>
}
// Any DataSource can be swapped
const apiSource: DataSource<User> = new ApiDataSource()
const mockSource: DataSource<User> = new MockDataSource()
I - Interface Segregation
Small, focused interfaces
// ❌ BAD
interface UserModule {
login(): void
logout(): void
updateProfile(): void
sendEmail(): void
}
// ✅ GOOD
interface Authenticatable { login(): void; logout(): void }
interface Editable { updateProfile(): void }
D - Dependency Inversion
Depend on interfaces, not implementations
// src/services/user.service.ts
import type { HttpClient } from '../interfaces/http.interface'
export function createUserService(client: HttpClient) {
return {
async getUser(id: string) {
return client.get(`/users/${id}`)
}
}
}
Templates
Component (< 50 lines)
// modules/users/components/UserCard.tsx
import type { UserCardProps } from '../src/interfaces/user.interface'
/**
* User card component.
*/
export function UserCard({ user, onEdit }: UserCardProps) {
return (
<div className="rounded-lg border p-4">
<h3>{user.name}</h3>
<p>{user.email}</p>
<button onClick={() => onEdit(user.id)}>Edit</button>
</div>
)
}
Custom Hook (< 30 lines)
// modules/users/src/hooks/useUser.ts
import { useState, useEffect } from 'react'
import type { User } from '../interfaces/user.interface'
import { userService } from '../services/user.service'
/**
* Fetch and manage user state.
*/
export function useUser(id: string) {
const [user, setUser] = useState<User | null>(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
userService.getById(id).then(setUser).finally(() => setLoading(false))
}, [id])
return { user, loading }
}
Service (< 40 lines)
// modules/users/src/services/user.service.ts
import type { User } from '../interfaces/user.interface'
/**
* User service for API calls.
*/
export const userService = {
async getById(id: string): Promise<User | null> {
const res = await fetch(`/api/users/${id}`)
if (!res.ok) return null
return res.json()
},
async getAll(): Promise<User[]> {
const res = await fetch('/api/users')
return res.json()
},
}
Import Patterns
// Module imports cores
import { Button } from '@/modules/cores/components/Button'
import { cn } from '@/modules/cores/lib/utils'
// Module imports own src
import type { User } from '../src/interfaces/user.interface'
import { useUser } from '../src/hooks/useUser'
Forbidden
- ❌ Coding without researching docs first
- ❌ Files > 100 lines
- ❌ Interfaces in component files
- ❌ Business logic in components
- ❌ Class components
- ❌ Missing JSDoc on exports
- ❌
anytype - ❌ Barrel exports (index.ts re-exports)
- ❌
useEffectfor data fetching (use TanStack Query or Router loaders)
スコア
総合スコア
60/100
リポジトリの品質指標に基づく評価
✓SKILL.md
SKILL.mdファイルが含まれている
+20
✓LICENSE
ライセンスが設定されている
+10
○説明文
100文字以上の説明がある
0/10
○人気
GitHub Stars 100以上
0/15
○最近の活動
3ヶ月以内に更新がある
0/10
○フォーク
10回以上フォークされている
0/5
✓Issue管理
オープンIssueが50未満
+5
✓言語
プログラミング言語が設定されている
+5
○タグ
1つ以上のタグが設定されている
0/5
レビュー
💬
レビュー機能は近日公開予定です