AI-generated components that follow your rules.
Most AI code generation is unreliable. You get components with missing accessibility, broken patterns, and inconsistent styling. Each generation is a roll of the dice. We can do better.
Instead of hoping AI understands your requirements, encode them as rules that cannot be violated. Generate components that always follow your patterns, use your design system, and include proper testing hooks.
// Your rules, enforced automaticallyletvalidateComponent= (code: string) => {
// ✅ Must use design system functions// ✅ Must include test selectors // ✅ Must have accessibility attributes// ❌ Cannot use direct CSS classes
}- Reliable generation - Components that follow your coding standards every time
- Design system integration - No more
className="bg-blue-500", uses your design tokens - Built-in testing - Every component includes test selectors and accessibility attributes
- ReScript/React focused - Type-safe components that compile correctly
git clone https://github.com/hew/protocol-ui
cd protocol-ui
npm install
# Add your OpenAI API key to .envecho"OPENAI_API_KEY=your-key-here"> .env
# Generate a component
npm run generate:componentThe CLI will prompt you for what you want to build:
? Describe the component: A button with primary and secondary variants
? Component name: ActionButton ? Interactive features? Yes
✅ Generated ActionButton.res
"A card component with title, content, and optional action button"
// InfoCard.resopenReactopenDesignSystemtypeprops= {
title: string,
content: string,
actionText?: string,
onAction?: unit=>unit,
}
// Test selectors for Playwrightletselectors= {
root: "[data-test-id='InfoCard']",
title: "[data-test-id='InfoCard-title']",
action: "[data-test-id='InfoCard-action']",
}
@react.componentletmake= (~title, ~content, ~actionText=?, ~onAction=?) => {
<divdata-test-id="InfoCard"className={cx([
"p-6", "border", "rounded-lg", "shadow-sm",
backgroundColorToClass(Surface)
])}>
<h3data-test-id="InfoCard-title"className={cx([
"text-lg", "font-semibold", "mb-2",
colorToClass(OnSurface)
])}>
{title->React.string}
</h3>
<pclassName={cx([
"text-base", "mb-4",
colorToClass(OnSurfaceVariant)
])}>
{content->React.string}
</p>
{switch (actionText, onAction) {
| (Some(text), Some(handler)) =>
<buttondata-test-id="InfoCard-action"className={cx([
"px-4",
"py-2", "rounded",
backgroundColorToClass(Primary),
colorToClass(OnPrimary)
])}
onClick={_=>handler()}
aria-label={`Action: ${text}`}>
{text->React.string}
</button>
| _=>React.null
}}
</div>
}Input → AI Generation → Validation → ReScript Component
The system generates ReScript code, then validates it against your rules before saving. If validation fails, it tries again until it gets it right.
src/ai-generator/ReScriptGenerator.res- AI generation logicscripts/theme.js- Automated color theming systemsrc/core/DesignSystem.res- Design system integration
Generated components must follow these patterns:
Required:
- Test IDs:
data-test-id="ComponentName" - Design system:
backgroundColorToClass(Primary)instead ofbg-blue-500 - Accessibility: ARIA labels on interactive elements
- ReScript types: Proper type annotations
Forbidden:
- Direct CSS classes:
className="bg-blue-500" - Missing test hooks
- Poor accessibility
Uses your design tokens instead of hardcoded values:
// ✅ Generated code uses design systemclassName={backgroundColorToClass(Primary)}
className={cx([colorToClass(OnSurface), "text-lg"])}
// ❌ Never generates direct classes className="bg-blue-500 text-white"// Validation prevents thisChange your theme with one command:
node scripts/theme.js "#1f2937" corporateEvery generated component includes test selectors:
// Auto-generated in every componentletselectors= {
root: "[data-test-id='MyComponent']",
button: "[data-test-id='MyComponent-button']",
}Use them in your tests:
// MyComponent.test.resopenPlaywrightlettestComponentClick=async () => {
letpage=awaitPage.create()
awaitPage.click(page, MyComponent.selectors.button)
awaitExpect.toBeVisible(Page.locator(page, MyComponent.selectors.root))
}Set your OpenAI API key:
echo"OPENAI_API_KEY=your-key-here"> .envnpm run dev # Start dev server
rescript -w # Watch ReScript files
npm run generate:component # Generate a componentMIT License - see LICENSE file for details.