Solar Roadmap
Four improvements informed by the AI-first UI framework landscape research. Each closes a gap between what Solar does today and what the leading systems (A2UI, OpenUI, GenUI) do.Priority order
- Structured errors — everything else builds on this
- Component registry — needed before compact serialization
- Slots / composition — extends the contract model
- Compact serialization — optimization, depends on registry
1. Structured error objects
Problem: Solar throws plain strings. An agent consuming a validation error can’t parse it programmatically — it has to regex a human-readable message. What we’re building: AContractError class that extends Error with structured fields an agent can act on directly.
- New:
framework/contract/ContractError.js - Modify:
framework/contract/types.js— replace allthrow new Error(...)withContractError
2. Component registry
Problem: Solar validates props once a component is called, but there’s no way for a model to know what components exist before generating code. Unknown components fail silently or at mount time with a generic error. What we’re building: A module-level registry. Components self-register on import. The registry exposes a machine-readable manifest — a model reads it before generating any composition code.ContractError with a fix instruction.
Files:
- New:
framework/registry.js - Modify:
framework/runtime/reconciler.js— guard against unregistered components - Modify:
components/Button.js,components/Counter.js— self-register on import - Modify:
framework/index.js— exportregistry
3. Slots (typed component composition)
Problem: Solar has no answer for the open question in FRAMEWORK.md: how does the contract model handle component composition? A parent receiving a child as a prop has no way to declare or enforce what that child should be. What we’re building: Aslot prop type. Components tag their output vnode with _source = name. Slot validation checks that tag.
- Modify:
framework/contract/types.js— addslottoTypes, add slot validation logic - Modify:
framework/contract/defineComponent.js— tag returned vnode with_source
4. Compact serialization (h())
Problem: createElement calls are verbose. A model generating a tree writes a lot of tokens per node. OpenUI benchmarked ~52% token reduction with a compact format.
What we’re building: An h() function that parses a compact array notation. Registry-aware — component names resolve to their registered function automatically.
h() is a pure vnode factory — no lifecycle, no state. Stateful components still go through mountComponent. The compact format is just a denser input for building vnode trees.
Files:
- New:
framework/h.js - Modify:
framework/index.js— exporth
Implementation order
| Step | File | Change |
|---|---|---|
| 1 | framework/contract/ContractError.js | Create |
| 2 | framework/contract/types.js | Use ContractError, add slot type |
| 3 | framework/contract/defineComponent.js | Tag vnode with _source |
| 4 | framework/registry.js | Create |
| 5 | framework/runtime/reconciler.js | Registry mount guard |
| 6 | framework/h.js | Create |
| 7 | framework/index.js | Export registry, ContractError, h |
| 8 | components/Button.js | Self-register |
| 9 | components/Counter.js | Self-register |
| 10 | demo/index.html | Add registry, h(), slot demo sections |
| 11 | demo/main.js | Wire up new demo sections |
Open questions (not in this iteration)
- Should
registry.manifest()be the primary interface for model context, or should there be a more structured schema format (JSON Schema, OpenAPI-style)? - Should slot
acceptssupport multiple component names —accepts: ['Button', 'IconButton']? - Is there a case for a lightweight dev server that reads the registry at startup and surfaces the manifest before any code runs?