Project Structure
This page describes the structure of a widget repository scaffolded by the AI Quickstart's /create-invent-widget skill. Use it as a reference for what each file does as you develop.
If you don't have a widget yet, follow the AI Quickstart first — this page assumes you have a scaffolded repo on your machine.
The current template is Tailwind CSS 4 + shadcn/ui + Rspack + Module Federation + Vitest.
Repository Structure
widgets-{vendor}-{widget-name}/
├── .claude/ # Claude Code project config
├── .husky/ # (legacy) git hooks — most projects use lefthook
├── .storybook/ # Storybook config (component playground)
├── .env.example # Example environment variables
├── .gitlab-ci.yml # CI/CD pipeline definition
├── .nvmrc # Pinned Node.js version
├── .npmrc / .npmignore # NPM registry & ignore config
├── .prettierrc.js # Prettier formatting config
├── .stylelintrc.js # Stylelint config
├── CLAUDE.md # Claude Code project instructions
├── README.md # Project README
├── LICENSE.md
├── eslint.config.js # ESLint flat config
├── invent-widget-prompt.md # Main AI prompt — canonical reference for widget dev
├── lefthook.yml # Pre-commit hooks
├── package.json # Dependencies and npm scripts
├── postcss.config.mjs # PostCSS config (Tailwind integration)
├── release.config.js # semantic-release config
├── rspack/ # Rspack build config (Module Federation)
│ ├── build-vars.js
│ ├── rspack.develop.js # Standalone dev build (npm run dev)
│ └── rspack.production.js # Production + federation builds
├── src/
│ ├── global.d.ts # Global TypeScript declarations
│ ├── main.tsx # Dev mode entry point
│ ├── mocks.tsx # Default mocked platform props for dev mode
│ ├── {widget-name}/ # Your widget — folder renamed by setup wizard
│ │ ├── components/ # Widget-specific UI building blocks
│ │ │ ├── widget-header/
│ │ │ ├── widget-loading/
│ │ │ ├── widget-error/
│ │ │ └── widget-no-data/
│ │ ├── preview/
│ │ │ └── {widget-name}-preview.tsx # Composer preview
│ │ ├── styles/ # global.css + theme.css (Tailwind layers)
│ │ ├── index.ts
│ │ ├── {widget-name}.tsx # Main widget component
│ │ ├── {widget-name}-settings.tsx # Settings panel component
│ │ └── {widget-name}.spec.tsx # Vitest tests
│ ├── local-dev-components/ # Dev-only helpers (not bundled in production)
│ │ ├── control-panel.tsx # In-app dev controls for tweaking props/theme
│ │ ├── debug-grid.tsx # Grid overlay for layout debugging
│ │ ├── local-layout-grid.tsx
│ │ ├── local-widget.tsx # Wraps your widget for standalone dev mode
│ │ ├── themes.ts # Mock theme values
│ │ ├── hooks/
│ │ └── constants.ts
│ ├── shared/
│ │ ├── components/widget-root/ # Widget root wrapper (Shadow DOM, etc.)
│ │ └── config/env.ts
│ ├── templates/ # HTML template + favicon for the dev server
│ └── test/setup.ts # Vitest setup file
├── tsconfig.json
├── vitest.config.ts # Vitest config
└── widget-config.json # Widget metadata + Module Federation exposes
Key Files
widget-config.json
Main widget configuration. Defines:
- Widget metadata —
id,port,name,vendorPrefix,widgetType - Module Federation
exposes— entry points the host loads (Widget, Settings, Preview) widgetDetails— title, type, description, tags, context rules (when the widget appears in the Micro App Library)settingsSchema—jsonSchema+uiSchemaconsumed by@invent/json-settings(RJSF v5) to render the settings paneldefaultProps— defaults applied when the widget is first added to a dashboard
This file is preconfigured during the AI Quickstart's /create-invent-widget flow (Step 4) and then maintained by the widget-update skill.
src/{widget-name}/{widget-name}.tsx
Main widget component. Receives platform props (httpClient, platformMeta, settings, hooks like useShareValue / useQueryData, etc.) and renders the widget UI.
src/{widget-name}/{widget-name}-settings.tsx
Settings panel component shown in the Dashboard Composer. Consumes the settingsSchema from widget-config.json and renders the form via @invent/json-settings.
src/{widget-name}/preview/{widget-name}-preview.tsx
Compact preview shown in the Micro App Library (the picker inside the Dashboard Composer). Should be lightweight — static or with minimal interactivity.
src/main.tsx + src/mocks.tsx + src/local-dev-components/local-widget.tsx
Entry point for standalone dev mode (npm run dev). main.tsx boots the app, mocks.tsx supplies fake platform props, and local-widget.tsx wraps your widget with the mocked context. None of these are bundled in production — they exist only for the standalone dev loop. (Federation dev mode uses npm run start_federation and loads the real platform from your portal — see Running & Versioning.)
src/shared/components/widget-root/
The widget's root wrapper — handles Shadow DOM isolation, theme injection, and CSS scoping when the widget is loaded by the host application.
invent-widget-prompt.md / CLAUDE.md
Reference prompts loaded by Claude Code (and other AI assistants) when developing inside this repo. CLAUDE.md is what Claude Code reads automatically; invent-widget-prompt.md is the canonical version maintained alongside this documentation.
rspack/rspack.develop.js / rspack.production.js
Rspack build configs. develop.js builds for npm run dev (standalone). production.js builds for production and federation modes (npm run build, npm run start_federation).