Flux Universal UI Modeling Language (UIML)
Version 1.0
Introduction
Flux is a high-level, declarative UI Modeling Language (UIML) designed as an AI-first modeling language that decouples UI definition from framework-specific implementation. It addresses the fundamental problem of UI fragmentation across web and mobile platforms by providing a single source of truth for interface design.
Flux allows architects to model user interfaces based on Component Composition and Semantic Intent rather than the specific constraints of React, SwiftUI, or Jetpack Compose. By defining the "What" and "Why" of your UI, Flux can be "rendered" into any target framework—generating idiomatic, native-feeling code for each platform.
AI-First Design
Flux is specifically designed to be easily generated by LLM coding agents while remaining perfectly human-readable and writable. The syntax prioritizes:
- Unambiguous structure that LLMs can reliably produce
- Clear semantic intent that reduces hallucination and errors
- Self-documenting patterns that are obvious to both humans and AI
- Consistent formatting that makes code generation predictable
This makes Flux an ideal target language for AI-assisted development workflows, where LLMs can rapidly scaffold UIs while developers maintain full control and readability.
The Generator Philosophy
Flux follows the principle of universal specification with target-specific implementation—the same philosophy used by Protocol Buffers, Smithy, and Capacitor. The language specification defines the complete UI model without framework constraints. Generators handle the reality of each framework through:
- Native implementations where the framework supports the pattern natively
- Composed implementations where multiple primitives combine to achieve the result
- Compile-time warnings when features require workarounds
- Compile-time errors when features cannot be implemented
This approach ensures your UI model remains portable and future-proof while giving you full transparency about what happens under the hood.
Language Philosophy
Flux is built on five core principles:
AI-First, Human-Friendly
Flux is designed as an AI-first modeling language - optimized for LLM code generation while maintaining exceptional human readability. The syntax is structured and predictable, making it easy for coding agents to generate correctly while keeping it intuitive for developers to read, write, and maintain. This dual optimization makes Flux ideal for modern development workflows that leverage both human expertise and AI assistance.
Component as Contract
UI components serve as a formal contract between the design system, the application code, and the data layer. They ensure that interface behavior is consistent across all platforms.
Composition Over Inheritance
Flux embraces composition as the primary mechanism for building complex UIs. Components are composed from simpler building blocks, creating a clear hierarchy that translates naturally to any framework.
Platform Independence
By abstracting the UI model, Flux eliminates framework lock-in. A component defined in Flux can render on web, iOS, Android, and desktop without rewriting your interface logic.
Flexible UX
Flux stands for "Flexible UX" - recognizing that UIs need to adapt to different screen sizes, input methods, and platform conventions while maintaining core functionality.
Core Building Blocks
Components
Components are the primary units of Flux. They represent reusable UI elements with props, state, and behavior.
component Button {
props: {
label: String,
variant: "primary" | "secondary" | "danger",
disabled: Boolean = false,
onClick: Handler<void>
}
styles: {
padding: 12 24,
borderRadius: 8,
fontSize: 16,
fontWeight: 600
}
states: {
hovered: Boolean = false,
pressed: Boolean = false
}
}
Layouts
Layouts define how components arrange their children. Flux provides semantic layout primitives that map to native implementations.
component UserProfile {
props: {
user: User,
onEdit: Handler<void>
}
layout: VStack {
spacing: 16,
padding: 20,
alignment: "center"
children: [
Image {
src: props.user.avatarUrl,
width: 80,
height: 80,
style: "rounded-full"
},
Text {
text: props.user.name,
style: "headline"
},
Text {
text: props.user.email,
style: "caption",
color: "muted"
},
Button {
label: "Edit Profile",
variant: "primary",
onClick: props.onEdit
}
]
}
}
Shapes (Data Structures)
Shapes define the structure of data passed between components. They ensure type safety across all generated implementations.
shape User {
id: String,
name: String,
email: String,
avatarUrl: String,
role: UserRole
}
enum UserRole {
ADMIN,
USER,
GUEST
}
Type System
Flux provides a comprehensive type system that maps to native types in each target framework.
Scalar Types
| Flux Type | Description | React | SwiftUI | Jetpack Compose |
|---|---|---|---|---|
String | Text content | string | String | String |
Integer | Whole numbers | number | Int | int |
Float | Decimal numbers | number | Double | double |
Boolean | True/false | boolean | Bool | bool |
Color | Color value | string | Color | Color |
Image | Image source | string | ImageSourcePropType | Image | Image |
Collection Types
- List<T>: Ordered collection
- Map<K, V>: Key-value pairs
- Set<T>: Unique values
Nullable Types
By default, all props are required. Use ? suffix to make optional.
component UserCard {
props: {
name: String, // Required
bio: String?, // Optional
website: String? // Optional
}
}
Handler Types
Handlers represent callbacks and event handlers:
type Handler<T> = (value: T) -> void
type AsyncHandler<T> = (value: T) -> Promise<void>
Layout System
Flux provides semantic layout primitives that work consistently across platforms.
Stack Layouts
VStack (Vertical Stack):
layout: VStack {
spacing: 16,
padding: 20,
alignment: "center" | "leading" | "trailing",
children: [...]
}
HStack (Horizontal Stack):
layout: HStack {
spacing: 12,
padding: 16,
alignment: "top" | "center" | "bottom",
children: [...]
}
ZStack (Depth Stack / Overlay):
layout: ZStack {
alignment: "center",
children: [
// Background
Image { src: "background.jpg" },
// Foreground
VStack { children: [...] }
]
}
Flexible Layouts
Grid:
layout: Grid {
columns: 3,
spacing: 16,
padding: 20,
children: [...]
}
List (Scrollable):
layout: List {
direction: "vertical" | "horizontal",
spacing: 8,
children: [...]
}
Conditional Rendering
component Dashboard {
props: {
isLoggedIn: Boolean,
user: User?
}
layout: VStack {
children: [
if (props.isLoggedIn) {
UserProfile { user: props.user }
} else {
LoginForm {}
}
]
}
}
Styling System
Flux uses a semantic styling system that maps to native styling approaches.
Inline Styles
component Card {
styles: {
backgroundColor: "#FFFFFF",
borderRadius: 8,
padding: 16,
shadowColor: "#000000",
shadowOpacity: 0.1,
shadowRadius: 8
}
}
Style Variants
component Button {
props: {
variant: "primary" | "secondary" | "danger"
}
styles: {
base: {
padding: 12 24,
borderRadius: 8,
fontSize: 16
},
variants: {
primary: {
backgroundColor: "#0066CC",
color: "#FFFFFF"
},
secondary: {
backgroundColor: "#F0F0F0",
color: "#333333"
},
danger: {
backgroundColor: "#CC0000",
color: "#FFFFFF"
}
}
}
}
Responsive Styles
component ResponsiveCard {
styles: {
base: {
padding: 16,
width: "100%"
},
breakpoints: {
mobile: { maxWidth: 640 },
tablet: { maxWidth: 1024 },
desktop: { maxWidth: null }
}
responsive: {
mobile: {
padding: 12
},
tablet: {
padding: 20,
width: "50%"
},
desktop: {
padding: 24,
width: "33%"
}
}
}
}
Design Tokens
tokens {
colors: {
primary: "#0066CC",
secondary: "#6C757D",
success: "#28A745",
danger: "#DC3545",
warning: "#FFC107",
text: {
primary: "#212529",
secondary: "#6C757D",
muted: "#ADB5BD"
},
background: {
default: "#FFFFFF",
surface: "#F8F9FA",
elevated: "#FFFFFF"
}
},
spacing: {
xs: 4,
sm: 8,
md: 16,
lg: 24,
xl: 32
},
typography: {
headline: {
fontSize: 24,
fontWeight: 700,
lineHeight: 1.2
},
body: {
fontSize: 16,
fontWeight: 400,
lineHeight: 1.5
},
caption: {
fontSize: 14,
fontWeight: 400,
lineHeight: 1.4,
color: "text.secondary"
}
}
}
State Management
Flux provides built-in state management patterns that translate to framework-native solutions.
Local State
component Counter {
props: {
initialValue: Integer = 0
}
state: {
count: Integer = props.initialValue
}
methods: {
increment(): void {
this.state.count += 1
},
decrement(): void {
this.state.count -= 1
}
}
layout: VStack {
spacing: 16,
alignment: "center",
children: [
Text {
text: `Count: ${state.count}`,
style: "headline"
},
HStack {
spacing: 8,
children: [
Button {
label: "-",
onClick: methods.decrement
},
Button {
label: "+",
onClick: methods.increment
}
]
}
]
}
}
Computed Properties
component ProductCard {
props: {
product: Product
}
computed: {
discountedPrice(): Float {
return props.product.price * (1 - props.product.discount)
},
isOnSale(): Boolean {
return props.product.discount > 0
}
}
layout: VStack {
children: [
Text { text: props.product.name },
if (computed.isOnSale) {
Text {
text: `$${computed.discountedPrice}`,
style: "price-sale"
}
} else {
Text {
text: `$${props.product.price}`,
style: "price"
}
}
]
}
}
Effects and Lifecycle
component UserProfile {
props: {
userId: String
}
state: {
user: User? = null,
loading: Boolean = false,
error: String? = null
}
effects: {
onMount() {
this.methods.loadUser()
},
onUpdate(changes: { userId: String }) {
if (changes.userId !== props.userId) {
this.methods.loadUser()
}
}
}
methods: {
async loadUser(): void {
this.state.loading = true
try {
const user = await api.fetchUser(props.userId)
this.state.user = user
} catch (error) {
this.state.error = error.message
} finally {
this.state.loading = false
}
}
}
}
Backend Integration
Flux provides plugin points for connecting to backend services.
API Integration
@backend(
type: "rest",
baseUrl: "https://api.example.com"
)
component UserList {
props: {
onUserClick: Handler<User>
}
state: {
users: List<User> = [],
loading: Boolean = false
}
backend: {
endpoints: {
fetchUsers: {
method: "GET",
path: "/users",
response: List<User>
}
}
}
effects: {
onMount() {
this.methods.loadUsers()
}
}
methods: {
async loadUsers(): void {
this.state.loading = true
const users = await this.backend.fetchUsers()
this.state.users = users
this.state.loading = false
}
}
}
Capacitor Integration
@backend(
type: "capacitor",
schema: "./schema.capacitor",
generator: "typescript"
)
component ProductList {
props: {
categoryId: String
}
state: {
products: List<Product> = []
}
// Automatically generated from Capacitor schema
backend: {
queries: {
products: capacitor.product.findByCategory(props.categoryId)
}
}
effects: {
onMount() {
this.state.products = await this.backend.queries.products
}
}
}
Navigation
Flux provides declarative navigation that works across platforms.
Route Definition
routes {
home: {
path: "/",
component: HomePage
},
userProfile: {
path: "/users/:userId",
component: UserProfile,
params: {
userId: String
}
},
settings: {
path: "/settings",
component: SettingsPage,
auth: required
}
}
Navigation Methods
component UserCard {
props: {
user: User
}
methods: {
goToProfile(): void {
navigate.to("userProfile", { userId: props.user.id })
}
}
layout: HStack {
onClick: methods.goToProfile,
children: [...]
}
}
Platform-Specific Code
When needed, Flux allows platform-specific implementations.
Conditional Platform Code
component CameraButton {
layout: Button {
label: "Take Photo",
onClick: methods.openCamera
}
methods: {
openCamera(): void {
@platform(web) {
// Web implementation using getUserMedia
navigator.mediaDevices.getUserMedia({ video: true })
}
@platform(ios) {
// iOS implementation using UIImagePickerController
UIImagePickerController.show({ sourceType: "camera" })
}
@platform(android) {
// Android implementation using CameraX
CameraX.startCamera()
}
}
}
}
CLI and Workflow
Commands
flux check
Validates the Flux model and checks target compatibility.
flux check --target react
# Output:
# ✓ components/Button.flux - Valid
# ✓ components/UserProfile.flux - Valid
# ⚠ components/CameraButton.flux - Platform-specific code detected
# ✓ 12 components checked
# ⚠ 1 warning
flux generate
Generates framework-specific implementations.
# Generate React components
flux generate --target react --output ./src/components
# Generate SwiftUI views
flux generate --target swiftui --output ./iOS/Views
# Generate multiple targets
flux generate --target react,vue,swiftui,compose --output ./gen
flux watch
Watch mode for hot reload during development.
flux watch --target react --output ./src/components
flux preview
Preview components in a live environment.
flux preview --component Button --target react
Generator Architecture
Flux uses a generator architecture similar to Capacitor and Smithy.
How Generators Work
- Parse Flux models into an abstract syntax tree (AST)
- Validate semantic rules (e.g., all props must have types)
- Check target compatibility and emit warnings
- Generate target-specific code:
- Framework components (React, Vue, SwiftUI, Jetpack Compose)
- Type definitions
- Style sheets
- Navigation boilerplate
Supported Targets
Web Frameworks
- React - Functional components with hooks
- Vue - Vue 3 composition API
- Next.js - Server and client components
- Svelte - Svelte 4+ components
Mobile Frameworks
- SwiftUI - Native iOS/macOS views
- Jetpack Compose - Modern Android UI
- Jetpack Compose - Modern Android UI toolkit
- React Native - JavaScript-based mobile
Desktop
- Electron - Web technologies for desktop
- Tauri - Rust-based desktop apps
Example: Complete Application
// Design tokens
tokens {
colors: {
primary: "#0066CC",
background: "#FFFFFF"
},
spacing: {
md: 16
}
}
// Data shapes
shape User {
id: String,
name: String,
email: String,
avatar: String
}
shape Post {
id: String,
title: String,
content: String,
author: User,
createdAt: Date
}
// Components
component Avatar {
props: {
src: String,
size: Integer = 40
}
layout: Image {
src: props.src,
width: props.size,
height: props.size,
style: "rounded-full"
}
}
component PostCard {
props: {
post: Post,
onLike: Handler<String>
}
state: {
liked: Boolean = false
}
methods: {
handleLike(): void {
this.state.liked = !this.state.liked
props.onLike(props.post.id)
}
}
layout: VStack {
spacing: 12,
padding: 16,
backgroundColor: tokens.colors.background,
borderRadius: 8,
children: [
HStack {
spacing: 12,
children: [
Avatar {
src: props.post.author.avatar,
size: 40
},
VStack {
spacing: 4,
children: [
Text {
text: props.post.author.name,
style: "headline"
},
Text {
text: formatDate(props.post.createdAt),
style: "caption"
}
]
}
]
},
Text {
text: props.post.title,
style: "title"
},
Text {
text: props.post.content,
style: "body"
},
HStack {
spacing: 8,
children: [
Button {
label: state.liked ? "Liked" : "Like",
variant: state.liked ? "primary" : "secondary",
onClick: methods.handleLike
}
]
}
]
}
}
// Routes
routes {
home: {
path: "/",
component: HomePage
},
post: {
path: "/posts/:postId",
component: PostDetail,
params: { postId: String }
}
}
Getting Started
1. Installation
The Flux CLI is distributed as self-contained native binaries for each platform. Releases are available on the Genairus GitHub releases page.
macOS
Homebrew (Recommended)
brew tap genairus/tap && brew install flux-cli
Manual (x86_64 and ARM)
mkdir -p flux-install/flux && \
curl -L https://github.com/genairus/flux/releases/latest/download/flux-cli-darwin-$(uname -m).zip \
-o flux-install/flux-cli.zip && \
unzip -qo flux-install/flux-cli.zip -d flux-install && \
mv flux-install/flux-cli-darwin-*/* flux-install/flux
sudo flux-install/flux/install
Linux
Manual (x86_64 and ARM)
mkdir -p flux-install/flux && \
curl -L https://github.com/genairus/flux/releases/latest/download/flux-cli-linux-$(uname -m).zip \
-o flux-install/flux-cli.zip && \
unzip -qo flux-install/flux-cli.zip -d flux-install && \
mv flux-install/flux-cli-linux-*/* flux-install/flux
sudo flux-install/flux/install
Windows
Scoop (Recommended)
scoop bucket add genairus https://github.com/genairus/scoop-bucket; `
scoop install genairus/flux-cli
Manual (x64)
Download flux-cli-windows-x86_64.zip from the releases page, extract it, then run install.bat as Administrator.
Verify Installation
flux --version
2. Initialize Project
mkdir my-app && cd my-app
flux init
# Output:
# ✓ Created flux.config.yaml
# ✓ Created components/ directory
# ✓ Created tokens.flux
3. Define Your First Component
Create components/Button.flux:
component Button {
props: {
label: String,
onClick: Handler<void>
}
layout: Button {
text: props.label,
onClick: props.onClick
}
}
4. Generate Code
flux generate --target react --output ./src/components
5. Use in Your App
import { Button } from './src/components';
function App() {
return (
<Button
label="Click me"
onClick={() => console.log('Clicked!')}
/>
);
}
Integration with Other Languages
Flux is part of the Genairus Software Factory ecosystem. It integrates seamlessly with all other generative domain languages:
With Chronos (Requirements)
Define user journeys in Chronos; Flux components can reference those journeys for traceability:
namespace com.acme.ui.checkout
use com.acme.requirements.checkout#GuestCheckout
@journey("GuestCheckout")
component CheckoutForm {
// This component implements the GuestCheckout journey
props: {
onComplete: Function
}
}
Benefit: Every UI component traces back to the business requirement it fulfills.
With Capacitor (Data Models)
Import Capacitor entities as prop types for type-safe UI components:
namespace com.acme.ui.orders
use com.acme.data.orders#Order
use com.acme.data.orders#OrderStatus
component OrderSummary {
props: {
order: Order // Type from Capacitor
}
layout: column {
text("Order #${order.id}")
text("Status: ${order.status}")
}
}
Benefit: UI components automatically typed against your data model. Refactor the entity, and all components update.
With Smithy (API Contracts)
Reference Smithy operations for backend integration:
namespace com.acme.ui.checkout
@backend(operation: "com.acme.api.orders#PlaceOrder")
async function submitOrder(input: PlaceOrderInput) {
const result = await PlaceOrderAPI.call(input)
return result
}
component CheckoutForm {
async function handleSubmit() {
const result = await submitOrder({
shippingAddress: this.state.address,
paymentMethod: this.state.payment
})
// Handle result
}
}
Benefit: Type-safe API calls with generated client SDKs.
With Fusion (Infrastructure)
Flux components are deployed as part of Fusion services:
// In Fusion
service CheckoutUI {
frontend: {
source: "../ui/checkout",
framework: flux,
target: react
}
}
Benefit: Complete deployment configuration from infrastructure to frontend.
Standalone Mode
Flux works perfectly without other languages. Define shapes inline:
namespace com.acme.ui.checkout
shape Order {
id: String
total: Money
status: String
}
component OrderSummary {
props: {
order: Order // Inline definition
}
}
Configuration for Integration
Enable integrations in flux.config.yaml:
version: "1.0"
targets:
react:
output: "./src/components"
swiftui:
output: "./iOS/Views"
integrations:
chronos:
requirements: "./requirements"
capacitor:
schema: "./data"
generator: "typescript"
smithy:
spec: "./api"
client: "typescript"
fusion:
infra: "./infrastructure"
For complete integration guide, see Languages Overview.
Best Practices
- Component Composition: Build complex UIs from simple, reusable components
- Design Tokens: Define your design system once, use everywhere
- Type Safety: Always define prop types and data shapes
- Platform Awareness: Use platform-specific code only when necessary
- Backend Integration: Leverage Capacitor and Smithy for type-safe data access