specgen-react-mui — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited specgen-react-mui (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
This skill generates a comprehensive specification document (Markdown) that serves as a blueprint for building a React Single Page Application. The spec is intended to be followed by a developer or a coding agent to produce a fully functional project scaffold.
The specification does NOT generate code. It produces a detailed, opinionated technical document describing every layer of the application — from Vite configuration to MUI theme to React Query patterns — so that implementation becomes a mechanical exercise.
These are the fixed versions the spec targets. Do not deviate unless the user explicitly requests different versions.
| Component | Version |
|---|---|
| React | 19.x |
| TypeScript | 5.x |
| Vite | 6.x |
| Material UI (MUI) | 6.x |
| MUI Icons | 6.x |
| MUI System | 6.x |
| React Router | 7.x |
| TanStack Query | 5.x |
| Zustand | 5.x |
| React Hook Form | 7.x |
| Zod | 3.x |
| Axios | 1.x |
| Node.js | 22.x LTS |
Include in the version table only when the corresponding integration is selected.
| Component | Version | When Selected |
|---|---|---|
| Keycloak | 26.x | Auth = Keycloak |
| oidc-client-ts | 3.x | Auth = Keycloak or OIDC |
| react-oidc-context | 3.x | Auth = Keycloak or OIDC |
| MUI X Data Grid | 7.x | DataGrid = yes |
| MUI X Charts | 7.x | Charts = yes |
| MUI X Date Pickers | 7.x | DatePickers = yes |
| Socket.io Client | 4.x | WebSocket = yes |
| react-i18next | 15.x | i18n = yes |
| i18next | 24.x | i18n = yes |
| React Quill (or similar rich text editor) | latest | RichText = yes |
The spec must include these in the npm configuration section (always):
Production dependencies:
react + react-dom — Core React@mui/material + @mui/icons-material — MUI component library and icons@emotion/react + @emotion/styled — MUI v6 styling enginereact-router-dom — Client-side routing@tanstack/react-query — Server state and data fetchingzustand — Global client state managementreact-hook-form — Form state management@hookform/resolvers — Zod integration for React Hook Formzod — Schema validationaxios — HTTP clientDevelopment dependencies:
typescript — Type checking@types/react + @types/react-dom — React type definitionsvite + @vitejs/plugin-react — Build toolingeslint + @typescript-eslint/* — LintingIf Auth = Keycloak or OIDC:
oidc-client-ts — OAuth2/OIDC PKCE clientreact-oidc-context — React context wrapper for oidc-client-tsIf DataGrid = yes:
@mui/x-data-grid — Advanced data grid componentIf Charts = yes:
@mui/x-charts — Chart componentsIf DatePickers = yes:
@mui/x-date-pickers — Date/time picker componentsdate-fns — Date manipulation libraryIf WebSocket = yes:
socket.io-client — WebSocket clientIf i18n = yes:
react-i18next + i18next — Internationalizationi18next-browser-languagedetector — Auto language detectioni18next-http-backend — Lazy translation loadingIf RichText = yes:
react-quill-new — Rich text editor (Quill-based, React 19 compatible)dompurify + @types/dompurify — HTML sanitization for rich text contentIf Reporting = yes:
xlsx — Client-side XLSX file generationpapaparse + @types/papaparse — Client-side CSV generationpuppeteer, express, cors — server-side HTML-to-PDF via headless ChromeGenerate the spec when the user provides an application name and version that corresponds to one of the custom applications defined in CLAUDE.md. The skill reads all required inputs from the project's context files — no interactive Q&A is needed for the core inputs.
The user invokes this skill by specifying the target application and version, for example:
/specgen-react-mui admin v1.0.4/specgen-react-mui admin v1.0.4 module:Hero Section/specgen-react-mui "Admin Portal" v1.0.4The skill then locates the matching context folder and reads all input files automatically.
Before starting any work, resolve the application folder first (see Input Resolution below), then check CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md does not exist, skip this check (first-ever execution for this application).<app_folder>/CHANGELOG.md exists, scan all ## vX.Y.Z headings and determine the highest version using semantic versioning comparison."Version {requested} is lower than the current application version {highest} recorded in <app_folder>/CHANGELOG.md. Execution rejected." Do NOT proceed with any work.This skill uses standardized input resolution. Provide:
| Argument | Required | Example | Description |
|---|---|---|---|
<application> | Yes | admin | Application name to locate the context folder |
<version> | Yes | v1.0.4 | Version to scope processing |
module:<name> | No | module:Hero Section | Limit generation to a single module |
The application name is matched against root-level application folders:
<number>_ prefix from folder names (e.g., 1_admin → admin)| File | Resolved Path |
|---|---|
| PRD.md | <app_folder>/context/PRD.md |
| Module Models | <app_folder>/context/model/ |
| HTML Mockups | <app_folder>/context/mockup/ |
| Output (specification) | <app_folder>/context/specification/ |
When a version is provided, only include user stories, NFRs, and constraints from versions <= the provided version. For example, if v1.0.4 is specified:
[v1.0.0], [v1.0.1], [v1.0.2], [v1.0.3], [v1.0.4][v1.0.5] or laterWhen module:<name> is provided:
SPEC.md for that specific moduleSPECIFICATION.md (root) gets a partial update — only that module's entry in the TOCis added or updated; all other TOC entries are preserved as-is
The specification is driven by six input sources read from the project's context files. The skill does NOT ask the user for auth, API backend URL, or optional component choices — it determines these automatically from the context.
From CLAUDE.md (already loaded in context), locate the target application under the Custom Applications section. Extract:
base URL, authentication provider, and optional components
The application name is used to derive:
admin-portal)VITE_ (standard Vite convention)Read <app_folder>/context/PRD.md. This file contains all user stories organized by module. Extract:
# System Module heading (e.g., Authentication,User Management). These become system-level features.
# Business Module heading (e.g., Hero Section,Product and Service). These become business-level features.
### User Story section contains tagged items.These define the functional requirements for each feature's API hooks, form schemas, and page components.
The user stories directly inform:
Important: Items with strikethrough (~~text~~) are deprecated — do NOT include them as active requirements. List them in the "Removed / Replaced" subsection of the traceability table.
### User Story, ### Non Functional Requirement,and ### Constraint section contains one or more version blocks formatted as [v1.0.x]. The skill must track the version tag for each item and carry it through to the generated specification's traceability section.
Within the same PRD.md, each module has a ### Non Functional Requirement section. These inform:
NFRs should be mapped to specific technical decisions in the spec — for example, an NFR stating "paginated with 10 items per page" confirms which React Query pagination pattern to use, while "must support filtering" confirms which Zustand slice manages filter state.
Within the same PRD.md, each module has a ### Constraint section. These define hard boundaries that the spec must enforce:
Constraints are embedded directly into the relevant module blueprint — they inform Zod validation schemas, API call parameters, and route guard configurations.
Read <app_folder>/context/model/MODEL.md first as the index, then read the individual module model files in each module subfolder.
MODEL.md provides:
Per-module files (e.g., model/hero-section/model.md):
Per-module schema (e.g., model/hero-section/schemas.json):
The module model directly maps to:
Read <app_folder>/context/mockup/MOCKUP.html first as the index page, then read the HTML files organized by role in subfolders.
MOCKUP.html provides:
Role-specific subfolders (e.g., mockup/admin/content/):
IMPORTANT — Role folders inform access control, NOT URL paths. The role-specific folder structure (e.g., mockup/admin/content/hero-section.html) determines:
<ProtectedRoute requiredRole="ADMIN" />It does NOT determine the URL path. The URL path is always module-based:
<Route path="/hero-section" /> — NOT <Route path="/admin/hero-section" />The mockup screens directly map to:
Before determining optional components, check PRD.md for the following extended sections:
If PRD.md contains an # Architecture Principle section, extract patterns that affect frontend decisions:
| Pattern to Extract | How It Influences the Specification |
|---|---|
| "Stateless REST API" | Confirms Axios + TanStack Query pattern for API calls |
| "Event-driven" / "WebSocket" / "real-time" | Include Socket.io client integration and real-time notification component |
| "API gateway" | Configure base URL to point to gateway rather than individual services |
| Backend framework mention | Validate API response format assumptions |
If the section is absent, proceed with existing CLAUDE.md-only detection.
If PRD.md contains a # Design System section with a file reference:
createTheme() configuration: palette, typography variants, component style overridesIf the section is absent, use default MUI theme (existing behavior).
If PRD.md contains a # High Level Process Flow section:
If the section is absent, derive UI flow from user stories only (existing behavior).
Instead of asking the user, the skill determines optional components by analyzing the dependencies listed in CLAUDE.md, the # Architecture Principle section in PRD.md (if present), and cross-referencing with PRD.md NFRs and constraints.
Examine the "Depends on" list in CLAUDE.md for the target application:
| Dependency Pattern | API Configuration |
|---|---|
| References another application's REST API | VITE_API_BASE_URL set to that app's base URL |
| References a Spring Boot backend | Include Spring Boot CORS headers note |
| No explicit backend | Include mock API / json-server note for development |
| Dependency / PRD Pattern | Auth Selection |
|---|---|
| References "Single Sign On" or "Keycloak" in CLAUDE.md dependencies | Auth = Keycloak |
| PRD.md has login user stories with email/password | Auth = Local (local JWT from API) |
| PRD.md constraint says "public access, no auth required" | Auth = none |
| PRD.md has only public-facing content (landing page) | Auth = none |
If Auth = Keycloak, also extract from CLAUDE.md:
<project-slug>-spahttp://localhost:8180/realms/<realm>admin → ADMIN, editor → EDITOR)If Auth = Local (API-managed JWT):
| PRD.md Pattern | Component Selection |
|---|---|
| NFRs mention "grid", "sortable columns", "bulk select", "export CSV" | DataGrid = yes |
| NFRs mention "chart", "bar chart", "pie chart", "graph", "statistics" | Charts = yes |
| NFRs mention "date picker", "date range", "calendar" | DatePickers = yes |
| NFRs mention "real-time", "live updates", "push notification", "WebSocket" | WebSocket = yes |
| PRD.md mentions multiple languages or localization | i18n = yes |
| User stories mention "rich text", "WYSIWYG", "formatted content", "HTML content" | RichText = yes |
| NFRs mention "report", "generate report", "report generation", "PDF report" | Reporting = yes |
| User stories describe generating/downloading PDF, Excel, or CSV reports | Reporting = yes |
| A "Report" module exists in PRD.md with NFRs defining a Report interface | Reporting = yes |
After analyzing all inputs, produce a determination summary before generating the spec. Present it to the user for confirmation:
Optional Component Determination:
- Backend API: http://localhost:<port>/api (from CLAUDE.md Port Allocation table → depends on backend app)
- Authentication: Keycloak PKCE (from CLAUDE.md → depends on Single Sign On)
- DataGrid: yes (from PRD.md → NFR mentions sortable user list with bulk actions)
- Charts: no
- DatePickers: yes (from PRD.md → hero section effective/expiration date fields)
- WebSocket: no
- i18n: no
- RichText: yes (from PRD.md → blog content editor requires rich text)
- Reporting: yes (from PRD.md → Report module with Report interface NFR)If the user disagrees with any determination, allow them to override before proceeding.
After determination, these values are needed. Most are derived automatically:
Auto-derived from context files:
<title> and MUI themeAuto-derived from CLAUDE.md (Port Allocation table):
Port Allocation table in the Custom Applications section of CLAUDE.md. Construct the base URL as http://localhost:<port>/api/v1. Do NOT hardcode 8080 — the port MUST match the allocated port for the backend application this SPA depends on.Optional (use sensible defaults if not found in context):
3000en10 (from NFRs, or fallback)Once inputs are gathered from context files and optional components are determined, generate the specification as a multi-file output split by module. Read the spec template at references/spec-template.md for the exact structure and content of each section. The template is the authoritative guide — follow it closely.
The specification is split into two categories:
routing, auth configuration, and application-level sections that apply across all modules.
self-contained specification covering that module's complete blueprint.
This split enables a coding agent to:
SPECIFICATION.md<module>/SPEC.mdImportant: The generated spec must use real module data from the context files, not generic placeholders. Specifically:
(e.g., heroSection, productService, blog — not module1, module2)
not placeholder fieldOne/fieldTwo
says "view list of hero sections", the hook needs useHeroSections())
admin/content/hero_section.html exists, there must be a matching route and page component). The route path is module-based (e.g., /hero-section), NOT role-prefixed (e.g., NOT /admin/hero-section).
traceability section must include its version tag (e.g., USA000030 [v1.0.4]). ALL traceability sub-tables (User Stories, NFRs, AND Constraints) MUST include the `| Version |` column.
subsection listing deprecated items — showing the removed ID, the version that removed it, the replacement ID (if any), and a brief reason.
<app_folder>/context/specification/
├── SPECIFICATION.md ↠TOC + shared/application-level specs
├── hero-section/
│ └── SPEC.md ↠Module blueprint for Hero Section
├── product-service/
│ └── SPEC.md ↠Module blueprint for Product and Service
├── blog/
│ └── SPEC.md ↠Module blueprint for Blog
├── ... ↠One folder per module from PRD.mdSPECIFICATION.md (Root)The root file contains the TOC and all shared/application-level sections. These are sections a coding agent implements first before any module work:
#### 1. Project Overview Project metadata, application description, technology stack summary, user roles, module index table linking to each module's SPEC.md.
#### 2. Package Configuration Complete package.json with all dependencies (core + selected conditional), npm scripts (dev, build, preview, lint, type-check), and Vite configuration.
#### 3. Application Configuration Vite vite.config.ts (with proxy for backend API), TypeScript tsconfig.json, ESLint config. All environment-sensitive values use VITE_ prefix in environment files.
#### 3a. Application Version Configuration The application MUST include a version value exposed via Vite environment variable with a default derived from the version argument provided during skill invocation. If multiple versions were provided, use the highest one.
In .env.development and .env.production:
VITE_APP_VERSION=1.0.3The application MUST expose this version in the footer of the layout. The shared layout component (e.g., src/components/Layout/Footer.tsx) must read import.meta.env.VITE_APP_VERSION and render it as: v{version} (e.g., v1.0.3).
The package.json version field MUST also be set to the version value (e.g., 1.0.3).
#### 3b. .env.development File Generation from ENVIRONMENT.md Generate .env.development and .env.production files at the project root. The .env.development file is populated by reading ENVIRONMENT.md from the project root, mapping credential and platform values to VITE_-prefixed environment variable names. The .env.production file uses placeholder values for production deployment.
Process:
ENVIRONMENT.md from the project rootENVIRONMENT.md (# Supporting 3rd Party Applicationsfor Keycloak host/realm/client); the backend API host/port comes from the # Port Allocation table in CLAUDE.md. Read any toolchain paths (e.g., Node.js) from DEVTOOL.md
VITE_ environment variable name.env.development with actual local values.env.production with production placeholder valuesExample `.env.development` output (derived from ENVIRONMENT.md):
# Backend API
VITE_API_BASE_URL=http://localhost:<port from CLAUDE.md Port Allocation table>/api/v1
# Authentication (Keycloak)
VITE_KEYCLOAK_URL=http://localhost:8180
VITE_KEYCLOAK_REALM=urp
VITE_KEYCLOAK_CLIENT_ID=sc-worker-mobile-spaRules:
import.meta.envTODOdevelopment (e.g., localhost, default ports)
.env.development and .env.production are gitignored#### 4. Directory Structure The complete source tree under src/. The structure follows feature-based architecture where each PRD module maps to a src/features/<module>/ folder. Read references/routing-patterns.md for the module folder layout.
#### 5. MUI Theme Configuration Custom MUI theme built from design tokens extracted from mockup screens. Includes color palette (primary, secondary, error, warning, success), typography (font family, sizes), shape (border-radius), and component overrides. Read references/component-patterns.md for theme setup patterns.
#### 6. Authentication Configuration (conditional — include only if Auth != none) If Auth = Keycloak: PKCE Authorization Code flow using oidc-client-ts + react-oidc-context. AuthProvider wraps the app, useAuth() hook exposes user and tokens, Axios interceptor attaches Bearer token, protected route component checks authentication. Read references/security-patterns.md for the full auth architecture.
If Auth = Local (API JWT): Login form submits to backend API, JWT stored in Zustand auth store (memory only, not localStorage), Axios interceptor attaches Authorization header, token refresh interceptor handles 401 responses, protected route component redirects unauthenticated users.
#### 7. Router Configuration React Router v7 route tree — lazy-loaded page components, protected routes with role guards, public routes, 404 fallback. Read references/routing-patterns.md for route patterns.
#### 8. API Client Configuration Axios instance with baseURL from VITE_API_BASE_URL, request/response interceptors for auth token injection, global error handling (toast notifications for 4xx/5xx), request timeout.
#### 9. Global State (Zustand) App-level Zustand stores: auth store (user info, token, login/logout actions), UI store (sidebar open/closed, theme mode, global loading). Feature-level stores defined in each module's SPEC.md.
#### 10. TanStack Query Setup QueryClient configuration with sensible defaults (staleTime, gcTime, retry logic), QueryClientProvider wrapping the app, React Query DevTools for development, global error handler for failed queries.
#### 11. Shared Layouts DashboardLayout (sidebar navigation + topbar + content area for authenticated pages), PublicLayout (minimal header/footer for public pages), AuthLayout (centered card for login/callback pages). Each layout uses MUI components.
#### 12. Shared Components Reusable MUI-based components used across multiple modules: PageHeader, DataTable (wrapper around MUI Table or X DataGrid), ConfirmDialog, StatusChip, FormDialog, ImageUpload, LoadingOverlay, EmptyState, ErrorBoundary, SearchInput, FilterBar. Each with TypeScript props interface.
#### 13. Navigation Configuration Sidebar navigation items derived from mockup sidebar files, organized by role. Each item has label, icon (MUI icon), path, and required role. Navigation is rendered dynamically based on the authenticated user's roles.
#### 14. Form Infrastructure FormProvider usage pattern from React Hook Form, Zod schema integration via zodResolver, reusable controlled input components (TextFieldController, SelectController, DatePickerController, SwitchController, AutocompleteController) that wrap MUI inputs with RHF Controller.
#### 15. Error Handling Strategy React ErrorBoundary component for rendering errors, Axios response interceptor for API errors, TanStack Query onError callback for query failures, Zod validation error message extraction utility, MUI Snackbar/Alert for user-facing error messages.
#### 16. Notification System MUI Snackbar + Alert stack for toast notifications. Zustand notification store with push(type, message) and dismiss(id) actions. NotificationProvider renders the active queue at the bottom of the viewport.
#### 17. Theming & Dark Mode MUI ThemeProvider with CssBaseline. Theme mode (light/dark) toggled via UI control, persisted to localStorage. useColorMode() hook wraps the toggle action. MUI createTheme() called with the extracted design tokens.
#### 18. Testing Strategy Overview: Vitest + React Testing Library for unit/component tests, MSW (Mock Service Worker) for API mocking in tests, Playwright for E2E tests. Per-feature test conventions matching the module spec.
#### 19. Build & Deployment Vite production build (npm run build), chunk splitting strategy (vendor chunk, per- feature lazy chunks), environment variable injection, static hosting notes (nginx config for SPA routing).
#### 20. Internationalisation (conditional — include only if i18n = yes) react-i18next setup, I18nextProvider wrapping the app, lazy-loaded translation namespaces per module (e.g., heroSection.json), useTranslation() hook usage pattern, language switcher component.
#### 21. WebSocket Integration (conditional — include only if WebSocket = yes) socket.io-client setup, connection management Zustand store, custom useSocket() hook, event subscription patterns, reconnection handling.
#### 22. Reporting (Puppeteer) (conditional — include only if Reporting = yes) Client-side report UI components and server-side Puppeteer PDF generation service. Includes report list page (MUI DataGrid or Card grid grouped by domain), report parameter form page (React Hook Form + Zod + MUI), report preview dialog (iframe-based HTML preview), useReportGeneration() hook orchestrating PDF/XLSX/CSV generation, renderReportHtml() utility using ReactDOMServer.renderToStaticMarkup() to produce self-contained HTML with Tailwind CDN for Puppeteer rendering, report layout components (React components rendering tabular/summary reports as HTML), client-side XLSX export via xlsx library, client-side CSV export via PapaParse, lightweight Node.js Express report service using Puppeteer for HTML-to-PDF conversion (deployed as sidecar or microservice), Vite proxy configuration for development. Report layouts are fully AI-agent-developed React components — no visual designers needed. Read references/reporting-patterns.md for the full reporting architecture.
<module>/SPEC.md (Per-Module)For EACH module from PRD.md and MODEL.md, create a folder named after the module (kebab-case, e.g., hero-section/) and generate a SPEC.md inside it.
Each module SPEC.md is a self-contained blueprint that a coding agent can pick up and implement independently (after the shared infrastructure is in place). It must include:
SPECIFICATION.mdmockup screen filenames, all with version tags
useQuery and useMutation hooks wrapping API functionsSee references/spec-template.md for the exact per-module template structure.
After all specification files are successfully generated, append an entry to CHANGELOG.md in the application folder (<app_folder>/CHANGELOG.md):
<app_folder>/CHANGELOG.md. If it does not exist, create it with: # Changelog
- This file tracks all skill executions by version for this application.
- The highest version recorded here is the current application version.
- Skills MUST NOT execute for a version lower than the highest version in this file.
---## {version} heading matching the current version.--- below the context header and before any existing ## vX.Y.Z section (newest-first ordering), with a new table header and the first row.| {YYYY-MM-DD} | {application_name} | specgen-react-mui | {module or "All"} | Generated React SPA technical specification |The generated specification is a folder of files, not a single document:
<app_folder>/context/specification/
├── SPECIFICATION.md ↠Root: TOC + shared/application-level specs
├── <module-1>/
│ └── SPEC.md ↠Module blueprint (self-contained)
├── <module-2>/
│ └── SPEC.md
├── <module-N>/
│ └── SPEC.mdThese constraints apply to every code sample in the generated spec:
TypeScript everywhere. All files use .tsx or .ts extensions. No .js or .jsx. No any type — use unknown with type narrowing, or proper type inference.
Feature-based architecture. Every module maps to src/features/<module>/. Nothing module-specific leaks into src/shared/ or src/lib/. Shared utilities must be genuinely reusable across at least two modules.
No localStorage for tokens. JWT access tokens are stored in Zustand memory store only. Refresh tokens may use httpOnly cookies (handled by backend). This prevents XSS token theft.
TanStack Query for all server state. Do not use Zustand or component state to cache API responses. TanStack Query manages all server-side data (fetching, caching, invalidation). Zustand manages only client-side UI state (filters, selections, modal open/closed).
React Hook Form + Zod for all forms. Do not use uncontrolled inputs or manual useState for form fields. Every form uses useForm() with zodResolver().
MUI components only. Do not mix component libraries. If a component is not natively available in MUI, build it using MUI primitives (Box, Stack, Typography, Paper). No Tailwind CSS in this skill (unlike the Spring Boot / Laravel skills).
Named exports for components. Use named exports (not default exports) for all component files to improve tree-shaking and refactoring.
Lazy loading for all page components. All route page components use React.lazy() for code splitting. The router uses <Suspense> with a loading fallback.
Consistent file naming:
PascalCase.tsx (e.g., HeroSectionList.tsx)camelCase.ts with use prefix (e.g., useHeroSections.ts)camelCase.ts (e.g., heroSectionApi.ts)camelCase.types.ts (e.g., heroSection.types.ts)camelCase.schema.ts (e.g., heroSection.schema.ts)camelCase.store.ts (e.g., heroSection.store.ts)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.