name: optimizer description: This skill should be used when the user asks to "optimize", "improve performance", "add caching", "use TanStack Query", "add state management", "use cache", "add URL state", or mentions Zustand, TanStack Form, nuqs, client-side fetching, optimistic updates, React Query, cacheTag, or revalidateTag. Provides best practices for state management, URL state, data fetching, forms, caching, and Next.js optimization.
| Need | Solution | Reference |
|---|---|---|
| Shared state between components | Zustand store | references/state-management.md |
| LocalStorage persistence | Zustand with persist | references/state-management.md |
| URL state (filters, pagination) | nuqs | references/nuqs.md |
| Client-side data fetching | TanStack Query hooks | references/client-side-fetch.md |
| Optimistic updates | TanStack Query mutations | references/client-side-fetch.md |
| Form handling | TanStack Form | references/forms.md |
| Server data on page load | Server Components | references/nextjs-optimization.md |
| Public page caching | "use cache: remote" + cacheTag | references/caching.md |
| Function result caching | "use cache" + cacheLife | references/caching.md |
| Cache invalidation | revalidateTag with "max" | references/caching.md |
| Request deduplication | React.cache() | references/caching.md |
"use client";
import { create } from "zustand";
type MyStore = {
value: string;
setValue: (value: string) => void;
};
export const useMyStore = create<MyStore>((set) => ({
value: "",
setValue: (value) => set({ value }),
}));
export function useMyData() {
const org = useCurrentOrg();
return useQuery({
queryKey: ["my-data", org?.id],
queryFn: async () => fetchData(org?.id ?? ""),
enabled: !!org?.id,
});
}
const form = useForm({
schema: MySchema,
defaultValues: { field: "" },
onSubmit: async (values) => {
mutation.mutate(values);
},
});
<Form form={form}>
<form.AppField name="field">
{(field) => <field.Input />}
</form.AppField>
<form.SubmitButton>Submit</form.SubmitButton>
</Form>
// Page with remote caching
export default async function PublicPage({ params }) {
"use cache: remote";
cacheLife("hours");
cacheTag(`page-${params.pageId}`);
const data = await fetchData(params.pageId);
return <PageRenderer data={data} />;
}
// Invalidate in server actions (AFTER database update)
await prisma.page.update({ ... });
revalidateTag(`page-${pageId}`, "max"); // Always use "max"
Do NOT use Zustand for:
- Server data (use TanStack Query)
- URL state (use nuqs)
- Form state (use TanStack Form)
Do NOT use TanStack Query for:
- Initial page data (use Server Components)
- One-time fetches that don't need caching
- Data that doesn't change
Import from: @/features/form/tanstack-form
Client Components:
- Interactive UI (forms, buttons)
- Browser APIs
- Real-time updates
- User preferences
references/client-side-fetch.md- TanStack Query hooks, API routes, pagination, optimistic updatesreferences/state-management.md- Zustand store patterns and persistencereferences/nuqs.md- URL state for filters, pagination, search with parsers and debouncereferences/forms.md- TanStack Form patterns, validation, auto-savereferences/caching.md- "use cache", cacheTag, cacheLife, revalidateTag, React.cache()references/nextjs-optimization.md- Server Components, Suspense, dynamic imports
External skill: For additional advanced patterns (eliminating waterfalls, bundle optimization, re-render optimization), also use the vercel-react-best-practices skill.