Vibe Codex для React и Next.js: компоненты, хуки, миграции
React-проект — это семь способов сделать одно и то же. Хороший ассистент выбирает один и держится за него.
Frontend живёт в зоне постоянного API-дрейфа: React 19, Server Components, новый Next.js, новый бандлер, новый router. Vibe Codex здесь полезен тем, что помнит конвенции вашего проекта, а не «среднюю по StackOverflow».
Контекст проекта — не «весь репозиторий»
Перед первой задачей стоит положить рядом .vibe/context.md — короткую шпаргалку о стеке. Vibe Codex прочтёт её и не будет предлагать useState там, где у вас RTK Query, и Redux там, где Zustand.
# .vibe/context.md
- React 19, Next.js 16 (app router)
- стейт: RTK Query + redux-toolkit, slices в /src/store/slices
- стили: MUI 7 + emotion, без styled-components
- тесты: Vitest + @testing-library/react
- запреты: class components, propTypes, дефолтный экспорт
Компонент с первого раза
$ vibe-codex "сделай Drawer для деталей заказа: \
принимает orderId, через RTK Query тянет /orders/:id, \
скелетон, ошибка, контент с табами Items / History"
[plan] 1 file: src/components/OrderDrawer.tsx
[generated]
'use client';
import { Drawer, Tabs, Tab, Skeleton, Alert, Box } from '@mui/material';
import { useState } from 'react';
import { useGetOrderQuery } from '@/store/api/orders';
interface Props {
orderId: string;
open: boolean;
onClose: () => void;
}
export function OrderDrawer({ orderId, open, onClose }: Props) {
const [tab, setTab] = useState<'items' | 'history'>('items');
const { data, isLoading, error } = useGetOrderQuery(orderId, {
skip: !open,
});
return (
<Drawer anchor="right" open={open} onClose={onClose}>
<Box sx={{ width: 480, p: 3 }}>
{isLoading && <Skeleton variant="rectangular" height={400} />}
{error && <Alert severity="error">Не удалось загрузить</Alert>}
{data && (
<>
<Tabs value={tab} onChange={(_, v) => setTab(v)}>
<Tab label="Items" value="items" />
<Tab label="History" value="history" />
</Tabs>
{tab === 'items' ? <ItemsList order={data} /> : <HistoryList order={data} />}
</>
)}
</Box>
</Drawer>
);
}
Заметьте: 'use client' сверху — потому что Drawer интерактивный. Vibe Codex знает разницу между Server и Client Components и не пытается вызвать хук в серверном компоненте.
Кастомный хук
$ vibe-codex "хук useDebouncedSearch<T>(fn, delay), \
отменяет предыдущий вызов, поддерживает AbortSignal"
[plan] 1 file: src/hooks/useDebouncedSearch.ts
[plan] 1 file: src/hooks/useDebouncedSearch.test.tsx
Тест сразу же — вместе с хуком. Без отдельной просьбы.
Миграция Class → Function
Старые компоненты с this.state и componentDidMount переезжают аккуратно: один файл — один коммит. Vibe Codex держит контракт пропсов, переносит lifecycle в эффекты и оставляет тесты зелёными.
$ vibe-codex migrate src/legacy/UserProfile.tsx --to functional
[diff] -142 +98 lines
[notes]
componentDidMount → useEffect(() => { ... }, [])
componentWillUnmount → return inside useEffect
this.setState({ x }) → setX(...)
refs.input → const inputRef = useRef<HTMLInputElement>(null)
[tests] 23/23 passing
Next.js: серверные действия и роутинг
App Router с Server Actions любит явность. Vibe Codex генерирует action-файл, валидацию zod-схемой и серверный revalidatePath — без необходимости напоминать.
$ vibe-codex "сделай Server Action createInvoice с zod-валидацией \
и revalidatePath('/invoices')"
«Хороший ассистент не учит React — он соблюдает конвенции вашего проекта. Это разница между „применил“ и „приклеил“».
Что Vibe Codex не делает на фронте
- Не лезет в
package.jsonбез явной просьбы — версии зависимостей не его территория. - Не предлагает «попробуй ещё библиотеку X». Если у вас MUI, остаётся MUI.
- Не использует
any. Если тип неизвестен — спрашивает. - Не пишет инлайн-стили там, где есть тема.
Скучный, но полезный приём
Перед PR запустите vibe-codex review --diff HEAD~1. Это десять секунд: модель прочитает diff и подсветит классику — забытый key, лишний useEffect, ненужный useMemo, проп без типа. Те самые комментарии, которые иначе ловит ревьюер уровнем выше.
React-разработка — это компромисс между скоростью и аккуратностью. Vibe Codex держит обе стрелки в зелёном: пишет быстро, но в рамках конвенций, которые вы уже устаканили.
Готов попробовать?
brew tap xrouter-chat/tap && brew install vibe-codex — и за 30 секунд ты в деле.
Поставить Vibe Codex →