From frontend-craft
Classifies frontend state into ownership categories (local UI, server, URL, global, browser persistence) and provides decision criteria for choosing state tools in React/Vue/Next.js/Nuxt apps.
How this skill is triggered — by the user, by Claude, or both
Slash command
/frontend-craft:fec-state-managementThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Determine clear ownership of front-end state to avoid global store bloat, duplicate caching, and derived state synchronization errors.
Determine clear ownership of front-end state to avoid global store bloat, duplicate caching, and derived state synchronization errors.
Don't choose Redux, Zustand, Pinia or Context first. First mark each state to its unique owner, and then decide on the tool.
| Status Type | Typical Example | Default Attribution |
|---|---|---|
| Local UI state | Pop-up window switch, tab, expand row, hover editing state | In-component state / ref |
| Form status | Input value, dirty field, validation error, submitting | Form library or form component |
| Server status | List, details, paging results, remote errors | Request cache library |
| URL status | Search terms, filter, sort, page number, selected tab | Routing parameters / search params |
| Global client status | Login users, topics, permission snapshots, shopping cart drafts | Global store |
| Browser persistent state | Drafts, preferences, offline queues retained across refreshes | Storage layer + state adapter |
type ReportsStateMap = {
search: "url";
selectedReportId: "url";
reports: "server-state-cache";
isFilterPanelOpen: "local-ui";
draftColumns: "browser-persistence";
};
Do not save a new copy of a value that can be inferred from props, server state, URL, or existing state.
interface Invoice {
id: string;
status: "draft" | "sent" | "paid";
}
function InvoiceList({ invoices }: { invoices: Invoice[] }) {
const paidInvoices = invoices.filter((invoice) => invoice.status === "paid");
return <span>{paidInvoices.length}</span>;
}
Priority is given to localization and combination in React; the global store is only introduced when cross-page, cross-feature or unified actions are required.
import { create } from "zustand";
interface WorkspaceState {
activeWorkspaceId: string | null;
setActiveWorkspaceId: (workspaceId: string) => void;
}
export const useWorkspaceStore = create<WorkspaceState>((set) => ({
activeWorkspaceId: null,
setActiveWorkspaceId: (activeWorkspaceId) => set({ activeWorkspaceId }),
}));
Decision order:
useState / useReducer.In Vue 3, use provide/inject for local cross-level transfer; use Pinia or the existing store of the project for global business status.
import { computed, readonly, ref } from "vue";
import { defineStore } from "pinia";
export const useSessionStore = defineStore("session", () => {
const userId = ref<string | null>(null);
const isSignedIn = computed(() => userId.value !== null);
function signIn(nextUserId: string) {
userId.value = nextUserId;
}
return {
userId: readonly(userId),
isSignedIn,
signIn,
};
});
When reconstructing the state, first make a state list, and then gradually move the read and write entries. Each step should keep the behavior verifiable.
interface StateMigrationItem {
name: string;
currentOwner: "component" | "context" | "store" | "query-cache" | "url";
targetOwner: "component" | "context" | "store" | "query-cache" | "url";
verification: string;
}
const migrationPlan: StateMigrationItem[] = [
{
name: "dashboard filters",
currentOwner: "store",
targetOwner: "url",
verification: "refreshing the page preserves filters through search params",
},
];
Load references/state-patterns.md when you need Store shape examples, selector patterns, URL state synchronization, persistence adapters, SSR boundaries, or review checklists.
Output status attribution list, selection reasons, store/API boundaries and verification steps. Key behaviors such as loading/error/empty, refresh, rollback, cross-routing, and permission changes should be retained during implementation.
npx claudepluginhub bovinphang/frontend-craftGuides frontend state management in React: local/global decisions, Zustand/Redux Toolkit/Jotai/MobX/Context, TanStack Query/SWR for server state, optimistic updates, XState machines. Use for store setup, migrations, re-render fixes.
Audits state libraries in React/Vue/Svelte/Angular apps, classifies server/client state, recommends Zustand/Jotai/Pinia for UI and React Query/SWR for caching/optimistic updates.
Guides state management decisions (local vs global), store structure, selectors, and re-render performance. Useful when creating stores or managing client-side state. Examples use Zustand.