Help us improve
Share bugs, ideas, or general feedback.
From orchestrator
Provides React patterns like compound components, render props, custom hooks, and HOCs for scalable frontend apps. Use for component design, state management, and best practices.
npx claudepluginhub devsforge/orchestrator --plugin orchestratorHow this skill is triggered — by the user, by Claude, or both
Slash command
/orchestrator:frontend-patternsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Modern React patterns and best practices for building scalable applications.
Guides implementation of modern React patterns: hooks, component composition, state management, performance optimizations, concurrent features. Use for building or refactoring components.
Provides frontend development patterns for React and Next.js, focusing on component composition, compound components, and render props for building maintainable UIs.
Provides frontend patterns for React and Next.js including component composition, compound components, render props, state management, data fetching, and performance optimization.
Share bugs, ideas, or general feedback.
Modern React patterns and best practices for building scalable applications.
// Parent provides context, children consume it
const Tabs = ({ children, defaultTab }) => {
const [activeTab, setActiveTab] = useState(defaultTab);
return (
<TabsContext.Provider value={{ activeTab, setActiveTab }}>
<div className="tabs">{children}</div>
</TabsContext.Provider>
);
};
Tabs.List = ({ children }) => <div className="tabs-list">{children}</div>;
Tabs.Tab = ({ id, children }) => {
const { activeTab, setActiveTab } = useTabsContext();
return (
<button
className={activeTab === id ? 'active' : ''}
onClick={() => setActiveTab(id)}
>
{children}
</button>
);
};
Tabs.Panel = ({ id, children }) => {
const { activeTab } = useTabsContext();
return activeTab === id ? <div>{children}</div> : null;
};
// Usage
<Tabs defaultTab="tab1">
<Tabs.List>
<Tabs.Tab id="tab1">Tab 1</Tabs.Tab>
<Tabs.Tab id="tab2">Tab 2</Tabs.Tab>
</Tabs.List>
<Tabs.Panel id="tab1">Content 1</Tabs.Panel>
<Tabs.Panel id="tab2">Content 2</Tabs.Panel>
</Tabs>
interface MousePosition {
x: number;
y: number;
}
const MouseTracker = ({
render,
}: {
render: (pos: MousePosition) => ReactNode;
}) => {
const [position, setPosition] = useState({ x: 0, y: 0 });
useEffect(() => {
const handleMove = (e: MouseEvent) => {
setPosition({ x: e.clientX, y: e.clientY });
};
window.addEventListener('mousemove', handleMove);
return () => window.removeEventListener('mousemove', handleMove);
}, []);
return <>{render(position)}</>;
};
// Usage
<MouseTracker
render={({ x, y }) => (
<div>Mouse: {x}, {y}</div>
)}
/>
// Reusable logic extraction
function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch {
return initialValue;
}
});
const setValue = (value: T | ((val: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue] as const;
}
function withAuth<P extends object>(Component: ComponentType<P>) {
return function AuthenticatedComponent(props: P) {
const { user, isLoading } = useAuth();
if (isLoading) return <Spinner />;
if (!user) return <Navigate to="/login" />;
return <Component {...props} />;
};
}
// Usage
const ProtectedDashboard = withAuth(Dashboard);
interface Store {
// State
items: Item[];
isLoading: boolean;
// Actions
fetchItems: () => Promise<void>;
addItem: (item: Item) => void;
removeItem: (id: string) => void;
}
const useStore = create<Store>((set, get) => ({
items: [],
isLoading: false,
fetchItems: async () => {
set({ isLoading: true });
try {
const items = await api.getItems();
set({ items, isLoading: false });
} catch {
set({ isLoading: false });
}
},
addItem: (item) => set((state) => ({
items: [...state.items, item],
})),
removeItem: (id) => set((state) => ({
items: state.items.filter((i) => i.id !== id),
})),
}));
// Selectors for performance
const useItems = () => useStore((s) => s.items);
const useIsLoading = () => useStore((s) => s.isLoading);
// Query keys factory
const todoKeys = {
all: ['todos'] as const,
lists: () => [...todoKeys.all, 'list'] as const,
list: (filters: string) => [...todoKeys.lists(), { filters }] as const,
details: () => [...todoKeys.all, 'detail'] as const,
detail: (id: string) => [...todoKeys.details(), id] as const,
};
// Queries
export const useTodos = (filters?: string) =>
useQuery({
queryKey: todoKeys.list(filters ?? ''),
queryFn: () => fetchTodos(filters),
});
// Mutations with optimistic updates
export const useUpdateTodo = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: updateTodo,
onMutate: async (newTodo) => {
await queryClient.cancelQueries({ queryKey: todoKeys.lists() });
const previous = queryClient.getQueryData(todoKeys.lists());
queryClient.setQueryData(todoKeys.lists(), (old) =>
old?.map((t) => (t.id === newTodo.id ? newTodo : t))
);
return { previous };
},
onError: (err, newTodo, context) => {
queryClient.setQueryData(todoKeys.lists(), context?.previous);
},
onSettled: () => {
queryClient.invalidateQueries({ queryKey: todoKeys.lists() });
},
});
};
// Memoize expensive calculations
const expensiveValue = useMemo(() => {
return items.filter(x => x.active).reduce((acc, x) => acc + x.value, 0);
}, [items]);
// Memoize callbacks
const handleClick = useCallback((id: string) => {
setSelected(id);
}, []);
// Memoize components
const MemoizedList = memo(({ items }: { items: Item[] }) => (
<ul>
{items.map(item => <li key={item.id}>{item.name}</li>)}
</ul>
));
// Lazy load routes
const Dashboard = lazy(() => import('./pages/Dashboard'));
const Settings = lazy(() => import('./pages/Settings'));
// With loading fallback
<Suspense fallback={<PageSkeleton />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
import { useVirtualizer } from '@tanstack/react-virtual';
function VirtualList({ items }: { items: Item[] }) {
const parentRef = useRef<HTMLDivElement>(null);
const virtualizer = useVirtualizer({
count: items.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 50,
});
return (
<div ref={parentRef} style={{ height: 400, overflow: 'auto' }}>
<div style={{ height: virtualizer.getTotalSize() }}>
{virtualizer.getVirtualItems().map((virtualItem) => (
<div
key={virtualItem.key}
style={{
position: 'absolute',
top: virtualItem.start,
height: virtualItem.size,
}}
>
{items[virtualItem.index].name}
</div>
))}
</div>
</div>
);
}
class ErrorBoundary extends Component<Props, State> {
state = { hasError: false, error: null };
static getDerivedStateFromError(error: Error) {
return { hasError: true, error };
}
componentDidCatch(error: Error, info: ErrorInfo) {
console.error('Error caught:', error, info);
}
render() {
if (this.state.hasError) {
return <ErrorFallback error={this.state.error} />;
}
return this.props.children;
}
}
// Focus management
const modalRef = useRef<HTMLDivElement>(null);
useEffect(() => {
modalRef.current?.focus();
}, []);
// ARIA attributes
<button
aria-label="Close modal"
aria-expanded={isOpen}
aria-controls="modal-content"
>
<CloseIcon />
</button>
// Keyboard navigation
const handleKeyDown = (e: KeyboardEvent) => {
switch (e.key) {
case 'ArrowDown':
setFocusedIndex(i => Math.min(i + 1, items.length - 1));
break;
case 'ArrowUp':
setFocusedIndex(i => Math.max(i - 1, 0));
break;
case 'Enter':
handleSelect(focusedIndex);
break;
}
};