Cross-Platform UI Workbench
Last updated: 2026-01-09
- Audience: Developers (intermediate)
- Scope: Overview and essential workflows for this area
- Non-scope: Deep API reference or internal design rationale
- Owner: Platform Team (confirm)
- Review cadence: Quarterly (confirm)
This repository is a library-first monorepo for building consistent UI across ChatGPT widgets and standalone React applications.
A cross-platform UI workbench for building ChatGPT-style interfaces across multiple platforms:
- ChatGPT Widgets - Embedded widgets via OpenAI Apps SDK
- React Applications - Standalone web applications using
@design-studio/ui - MCP Integration - Model Context Protocol server for ChatGPT tool integration
@design-studio/ui- Reusable UI components (chat layout, header, sidebar, primitives)@design-studio/runtime- Host adapters + mocks (window.openaiwrapper, HostProvider)@design-studio/tokens- Design tokens (CSS variables, Tailwind preset)packages/widgets- Standalone widget bundles for ChatGPTpackages/cloudflare-template- Cloudflare Workers deployment template for MCP
platforms/web/apps/web- Widget Gallery for visual testing and MCP widget buildsplatforms/web/apps/storybook- Component documentation and interactive developmentplatforms/desktop/apps/desktop- Desktop shell scaffold (Tauri placeholder)platforms/mcp- MCP server for ChatGPT integration
Note: apps/ is a navigation index only; canonical app paths remain under platforms/.
- Prerequisites
- Compatibility matrix
- Quick Start
- Verify
- Common tasks
- Widget Gallery & Development
- Documentation
- Troubleshooting
- Rules of the road
- Apps SDK UI integration
- Foundation tokens (audit layer)
- Host adapter seam
- Library exports
- Public API surface
- Public API policy
- Storybook navigation
- Release & versioning
- Using in Other Projects
- Creating New Components
- Development Workflow
- Architecture
- Node.js 18+
- pnpm 10.28.0 (see
packageManagerinpackage.json)
- React: 19.x (required by
@design-studio/uipeerDependencies) - TypeScript: 5.9+ (workspace devDependency)
- Node.js: 18+ (runtime baseline)
- Apps SDK UI: ^0.2.1 (from
@design-studio/uidependencies)
# Install dependencies
pnpm install
# Start development
pnpm dev # Widget Gallery at http://localhost:5173
pnpm dev:web # Widget Gallery only (http://localhost:5173)
pnpm dev:storybook # Storybook only (http://localhost:6006)
# Build for production
pnpm build # Build pipeline (web packages)
pnpm build:web # Web-only build
pnpm build:widgets # Widget bundles
pnpm build:widget # Single-file widget HTML (for MCP harness)- Widget Gallery: open http://localhost:5173/
- Storybook: open http://localhost:6006/
Core scripts you'll use frequently:
# Development
pnpm dev # Widget Gallery only
pnpm dev:web # Widget Gallery only
pnpm dev:storybook # Storybook only
pnpm dev:widgets # Widget development mode
# MCP Server
pnpm mcp:dev # MCP server in development mode
pnpm mcp:start # MCP server in production mode
# Testing
pnpm test # UI unit tests (Vitest) - Tier 1
pnpm test:agent-browser # Built-preview smoke tests - Tier 2
pnpm test:agent-browser:ci # CI smoke tests (build + serve + test) - Tier 2
pnpm storybook:test # Component tests
pnpm test:e2e:web # End-to-end tests (Playwright)
pnpm test:a11y:widgets # Accessibility tests for widgets
pnpm test:visual:web # Visual regression tests (web)
pnpm test:visual:storybook # Visual regression tests (Storybook)
pnpm test:mcp-contract # MCP tool contract tests
# Code Quality
pnpm lint # Biome
pnpm format # Biome (write)
pnpm format:check # Biome (check only)
pnpm lint:compliance # Check compliance rules
pnpm doc:lint # Vale sync + markdown linting + link check
# Building
pnpm build # Full build pipeline
pnpm build:web # Web-only build
pnpm build:widgets # Widget bundles for production
pnpm build:widget # Single-file widget HTML for MCP
pnpm build:lib # Build @astudio packages only
# Utilities
pnpm new:component # Component generator
pnpm sync:versions # Sync package versions across workspace
pnpm validate:tokens # Validate design token consistencyThe repo includes a unified CLI wrapper for common dev/build/test/MCP tasks:
pnpm astudio --help
pnpm astudio dev
pnpm astudio build web
pnpm astudio test e2e-web
pnpm astudio mcp tools list
pnpm astudio doctorThe web app (platforms/web/apps/web) is a Widget Gallery for visual testing and MCP widget builds:
- Widget Gallery: http://localhost:5173/ (default) - Browse and test all aStudio widgets in iframe previews
- Widget Harness: http://localhost:5173/harness - Test individual widgets with modal controls
- 12+ widgets including Dashboard, Chat View, Search Results, Compose, and Kitchen Sink
- Iframe-based widget isolation for accurate testing
- Built-in modal testing (Settings, Icon Picker, Discovery Settings)
- Keyboard shortcuts (
?for help,Gfor next widget)
pnpm build:widgetThis creates platforms/web/apps/web/dist/widget.html (a single-file HTML bundle used by the MCP server).
If you're building a custom application with page routing, see PAGES_QUICK_START.md for guidance on adding new pages to your application.
Use this table to jump to the canonical doc surface. For more detail, see
docs/README.md.
| Area | Doc |
|---|---|
| Project overview | README.md |
| Docs index | docs/README.md |
| Guides index | docs/guides/README.md |
| Architecture | docs/architecture/README.md |
| Repo map | docs/architecture/repo-map.md |
| Build pipeline | docs/BUILD_PIPELINE.md |
| Restructure migration | docs/guides/repo-structure-migration.md |
| Web Widget Gallery | platforms/web/apps/web/README.md |
| Storybook | platforms/web/apps/storybook/README.md |
| MCP server | platforms/mcp/README.md |
| Tokens | packages/tokens/README.md |
| UI components (React) | packages/ui/README.md |
| Runtime host | packages/runtime/README.md |
| Widgets | packages/widgets/README.md |
Cause: pnpm is not installed. Fix:
npm install -g pnpmCause: MCP server is not running or the URL is wrong. Fix:
pnpm mcp:startThen confirm the MCP URL in the aStudio app settings panel (default http://localhost:8787).
Cause: Dependencies not installed or Node version mismatch. Fix:
pnpm install
node -v-
packages/ui
β UI only (components, layouts, stories)
β Depends on@openai/apps-sdk-uifor styling
β Icons come frompackages/ui/src/icons(Apps SDK UI first, Lucide fallback)
β Nowindow.openai
β No MCP logic
β No real network calls (only via injected host)
β No directlucide-reactimports (usepackages/ui/src/iconsadapter)
β No@mui/*(warn-only for now)
β No direct@radix-ui/*imports outsidepackages/ui/src/primitives(warn-only) -
packages/runtime
β Host interface + adapters
βcreateEmbeddedHost()wrapswindow.openai
βcreateStandaloneHost()uses your API/mocks
β No UI components -
platforms/web/apps/web
β Widget Gallery for visual testing
β Builds single-file widget HTML for MCP
β Standalone host adapter implementation
β No reusable UI source -
platforms/web/apps/storybook
β Component documentation and interactive development
β Design system showcase
β No reusable UI source -
platforms/mcp
β MCP server (serves widgets and defines tool contracts)
β ChatGPT integration layer
β Not required for library usage (only for ChatGPT integration)
This repo uses Apps SDK UI as the visual system. Import the CSS in both standalone and embedded builds:
@import "tailwindcss";
@import "@openai/apps-sdk-ui/css";
@import "@design-studio/tokens/foundations.css";
/* Tailwind v4 scanning */
@source "../node_modules/@openai/apps-sdk-ui";
@source "../../packages/ui/src";See: https://developers.openai.com/apps-sdk/
@design-studio/tokens encodes the PDF "Figma foundations" as:
packages/tokens/src/foundations.css(CSS variables)packages/tokens/src/*.ts(TS exports for Storybook foundations pages)
Source PDFs live in docs/foundations/chatgpt-apps/.
These tokens are audit/extension only. Use Apps SDK UI classes/components in UI.
packages/runtime exposes a Host interface + provider, so components stay host-agnostic:
import { HostProvider, createStandaloneHost } from "@design-studio/runtime";
const host = createStandaloneHost("http://localhost:8787");For embedded ChatGPT apps, use createEmbeddedHost() which wraps window.openai.
Runtime details and widgetSessionId guidance live in packages/runtime/README.md.
The UI package re-exports chat components and UI primitives from a single entry point.
import { Button, ChatHeader, ChatSidebar } from "@design-studio/ui";For production code, prefer subpath exports for better tree-shaking:
import { Button } from "@design-studio/ui/base";
import { ModelSelector } from "@design-studio/ui/navigation";
import { ChatSidebar } from "@design-studio/ui/chat";Demo pages and sandbox utilities are exposed from a separate entry to keep the production surface clean:
import { AStudioApp, DesignSystemPage } from "@design-studio/ui/dev";Experimental or fast-evolving APIs are exposed separately:
import { ChatFullWidthTemplate } from "@design-studio/ui/experimental";| Category | Exports (examples) |
|---|---|
| Chat UI components | ChatUIRoot, ChatHeader, ChatSidebar, ChatMessages, ChatInput, ComposeView |
| UI primitives | Button, Dialog, Tabs, Tooltip, and more |
| Icons | Icons adapter, ChatGPTIcons |
| Pages | DesignSystemPage, TypographyPage, SpacingPage (via @design-studio/ui/dev) |
| Templates | ChatFullWidthTemplate, ChatTwoPaneTemplate, DashboardTemplate (experimental) |
| Utilities | useControllableState |
- Stable:
@design-studio/uiroot exports and the@design-studio/ui/app,@design-studio/ui/chat,@design-studio/ui/modals,@design-studio/ui/settings,@design-studio/ui/base,@design-studio/ui/data-display,@design-studio/ui/feedback,@design-studio/ui/forms,@design-studio/ui/layout,@design-studio/ui/navigation,@design-studio/ui/overlays,@design-studio/ui/icons, and@design-studio/ui/showcasesubpaths. - Experimental:
@design-studio/ui/experimentaland@design-studio/ui/templates(subject to breaking changes). - Dev-only:
@design-studio/ui/devis for Storybook, docs, and local harnesses (not production).
- Overview: onboarding, galleries, and page previews
- Documentation: system docs + design system
- Components: UI primitives, chat surfaces, templates, icons, integrations
This repo uses Changesets for versioning and release automation:
pnpm changeset
pnpm version-packages
pnpm releaseRun the MCP harness (optional):
pnpm mcp:startCompliance warnings (non-blocking for now):
pnpm lint:complianceSet COMPLIANCE_STRICT=1 to turn warnings into errors.
If your other projects are in the same monorepo:
{
"dependencies": {
"@design-studio/ui": "workspace:*",
"@design-studio/runtime": "workspace:*",
"@design-studio/tokens": "workspace:*"
}
}Add this repo as a submodule in your project:
git submodule add <repo-url> packages/astudioThen reference in your package.json:
{
"dependencies": {
"@design-studio/ui": "file:./packages/astudio/packages/ui"
}
}Publish to npm or GitHub Packages:
pnpm build:lib
pnpm changeset
pnpm version-packages
pnpm releaseThen install normally:
pnpm add @design-studio/ui @design-studio/runtime @design-studio/tokensUse the component generator:
# Create a primitive component (Button, Input, etc.)
pnpm new:component MyButton primitive
# Create a chat component
pnpm new:component ChatToolbar chat
# Create a template
pnpm new:component AdminTemplate template
# Create a page
pnpm new:component SettingsPage pageThis creates the component file and a Storybook story.
π For the complete component creation workflow including planning, testing, and release, see docs/guides/COMPONENT_CREATION.md.
- Design in Storybook -
pnpm dev:storybook- Interactive component development and documentation - Test in Widget Gallery -
pnpm dev:web- Visual testing of widget bundles in isolation - Build Widgets -
pnpm build:widgets- Create production widget bundles - Test in ChatGPT -
pnpm mcp:start- Run MCP server for ChatGPT integration
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Your Projects β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β React App β ChatGPT Widget β ... β
β (Standalone) β (Embedded) β β
βββββββββ¬ββββββββ΄βββββββββ¬βββββββββ΄βββββββββββββββββββββββββ
β β
ββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/ui (React) β
β Component Library β
ββββββββββββββββββββββββββββ€
β β’ Chat Components β
β β’ UI Primitives β
β β’ Templates β
β β’ Pages β
βββββββββ¬βββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/runtime β
β (Host Abstraction) β
ββββββββββββββββββββββββββββ€
β β’ createEmbeddedHost() β
β β’ createStandaloneHost()β
β β’ HostProvider β
βββββββββ¬βββββββββββββββββββ
β
βββββββββΌβββββββββββββββββββ
β @design-studio/tokens β
β (Design Tokens) β
ββββββββββββββββββββββββββββ€
β β’ CSS Variables β
β β’ Tailwind Preset β
β β’ Theme Configuration β
ββββββββββββββββββββββββββββ
The repository supports React implementations across web, widgets, and Tauri shells:
- React: Uses
@design-studio/ui,@design-studio/runtime, and@design-studio/tokens - Design Parity: All surfaces share the same design tokens and visual language from Apps SDK UI
brAInwav
from demo to duty