From common-skills
Feature-Sliced Design architecture patterns. Activated when working with FSD layers, slices, dependency rules, or structuring frontend code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/common-skills:fsd-architectureThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Feature-Sliced Design - frontend standard architecture
Feature-Sliced Design - frontend standard architecture
src/
├── app/ # App init, providers, router, global styles
├── pages/ # Route entry points (composition only, no logic)
├── widgets/ # Independent UI block compositions
├── features/ # User actions (login, like, comment)
├── entities/ # Business entities (User, Product, Order)
└── shared/ # Common utils, UI Kit, API client
app → pages, widgets, features, entities, shared
pages → widgets, features, entities, shared
widgets → features, entities, shared
features → entities, shared
entities → shared
shared → (external libraries only)
Import only from lower layers. No exceptions.
// features/auth/ui/login-form.tsx
import { User } from '@/entities/user'; // OK: lower layer
import { Button } from '@/shared/ui'; // OK: lower layer
// entities/user/model/hooks.ts
import { useAuth } from '@/features/auth'; // FORBIDDEN: upper layer
// features/auth/ui/login-form.tsx
import { useProfile } from '@/features/profile'; // FORBIDDEN: same layer cross-slice
features/auth/
├── ui/ # Components
│ ├── login-form.tsx
│ └── logout-button.tsx
├── model/ # State, types
│ ├── types.ts
│ └── store.ts
├── api/ # API calls, React Query
│ ├── queries.ts
│ └── mutations.ts
├── lib/ # Utilities
│ └── validate-token.ts
└── index.ts # Public API (required)
Every slice must export through index.ts.
// features/auth/index.ts
export { LoginForm } from './ui/login-form';
export { LogoutButton } from './ui/logout-button';
export { useLoginMutation } from './api/mutations';
export type { LoginCredentials } from './model/types';
// OK
import { LoginForm, useLoginMutation } from '@/features/auth';
// FORBIDDEN: direct internal access
import { LoginForm } from '@/features/auth/ui/login-form';
| Layer | Role | Key Rules |
|---|---|---|
| app/ | Provider setup, global styles, router config | No business logic |
| pages/ | Route entry points | Compose widgets/features only, no business logic |
| widgets/ | Independent UI blocks | Combine features + entities, page-ready units |
| features/ | User action units | Business logic, mutations live here |
| entities/ | Business entities | Type definitions, queries (read-only) |
| shared/ | Project-independent code | UI Kit, utilities, API client |
// pages/dashboard/index.tsx
export function DashboardPage() {
return (
<PageLayout>
<DashboardHeader /> {/* widgets */}
<DashboardStats /> {/* widgets */}
<RecentActivity /> {/* widgets */}
</PageLayout>
);
}
// widgets/user-profile/index.tsx
export function UserProfile({ userId }: Props) {
const { data: user } = useUser(userId);
const { mutate: follow } = useFollowMutation();
return (
<Card>
<UserAvatar user={user} />
<UserInfo user={user} />
<FollowButton onFollow={() => follow(userId)} />
</Card>
);
}
// features/like-post/api/mutations.ts
export const useLikePostMutation = () => {
return useMutation({
mutationFn: (postId: string) => api.post(`/posts/${postId}/like`),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: postKeys.all });
},
});
};
// entities/user/api/queries.ts
export const userQueries = {
detail: (id: string) => queryOptions({
queryKey: ['user', id],
queryFn: () => api.get<User>(`/users/${id}`),
}),
};
| Target | Rule | Example |
|---|---|---|
| Layer | lowercase | features, entities |
| Slice | kebab-case | user-profile, create-post |
| Component file | kebab-case | login-form.tsx |
| Component | PascalCase | LoginForm |
| Hook | camelCase | useUser, useLoginMutation |
| Type | PascalCase | User, LoginCredentials |
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
}
}
When circular references occur, move shared types to shared:
// shared/types/index.ts
export interface BaseUser { id: string; name: string; }
export interface BasePost { id: string; authorId: string; }
index.ts public APIpages/ layerentities/ layer (read-only)npx claudepluginhub dding-g/ddingg-claude-marketplace --plugin common-skillsEnforces Suspense-first data fetching, feature-based code organization, and strict TypeScript discipline for React applications. Use when creating components, pages, adding features, or fetching data.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.