Skip to content

Full-Stack Project

This tutorial walks through setting up a monorepo project with a FastAPI backend and a Next.js frontend, both powered by Honey Badgeria's architecture layer.

Scaffold the Monorepo

hbia init my_app --framework monorepo
cd my_app

This creates:

my_app/
├── hbia.yaml                     # Root monorepo configuration
├── README.md
├── back/                         # FastAPI + HBIA backend
│   ├── flows/                    # YAML flow definitions
│   │   └── example_flow.yaml
│   ├── vertices/                 # Python handlers
│   │   └── greetings.py
│   ├── tests/                    # Backend tests
│   │   └── test_flow_example.py
│   ├── infra/                    # Infrastructure (auth, etc.)
│   │   └── auth.py
│   ├── app.py                    # FastAPI application
│   ├── manage.py                 # Management script
│   ├── settings.py               # Backend settings
│   ├── requirements.txt
│   ├── hbia.yaml
│   └── .env                      # Environment variables
├── front/                        # Next.js + HBIA frontend
│   ├── app/                      # Next.js App Router
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   │   └── globals.css
│   ├── graph/                    # UI, State, Effect, Event YAMLs
│   │   └── counter/
│   │       ├── ui/
│   │       ├── state/
│   │       ├── effects/
│   │       └── events/
│   ├── primitives/               # Reusable UI components
│   ├── services/                 # API service layer
│   ├── hbia-runtime/             # Generated TypeScript (from codegen)
│   ├── hbia.yaml
│   ├── package.json
│   ├── tsconfig.json
│   ├── next.config.ts
│   ├── tailwind.config.ts
│   └── postcss.config.js
└── AGENTS.md

Backend Setup

cd back
pip install fastapi uvicorn
pip install honey-badgeria[dev]
python manage.py

The backend follows the same patterns described in the FastAPI Integration tutorial. Define flows in YAML, implement handlers in Python, and HBIA generates REST endpoints.

Frontend Setup

cd ../front
npm install

The frontend uses HBIA's reactive graph system — a fundamentally different approach to frontend architecture.

The Four Graphs

Instead of building UIs with traditional component-based patterns where components own state, effects, and event handling, HBIA decomposes the frontend into four interconnected reactive graphs:

  1. UI Graph — Component hierarchy. Pure render functions with no hooks, no state, no effects.
  2. State Graph — State ownership. Typed fields, mutations, and effect triggers.
  3. Effect Graph — Side effects triggered by state changes or events.
  4. Event Graph — User interaction flows mapping to ordered mutation sequences.

The fundamental rule: Events → mutate State → trigger Effects → State drives UI.

Define a UI Component

# graph/dashboard/ui/Dashboard/dashboard_node.yaml
component: Dashboard
view: dashboard_view
reads:
  - FilterState.dateRange
  - FilterState.region
  - ChartState.series
  - ChartState.loading
events:
  refresh: refresh_chart_event
  export: export_chart_event
children:
  - ChartHeader
  - ChartCanvas
  - ChartLegend

UI nodes are pure render functions. They:

  • Read state via reads (subscriptions)
  • Emit events via events
  • Have children (composing the component tree)
  • Never contain hooks, state management, or side effects

Define State

# graph/dashboard/state/FilterState/state.yaml
state: FilterState
interface: FilterStateData
fields:
  dateRange: DateRange
  region: string
  category: string
mutations:
  - set_date_range
  - set_region
  - set_category
  - reset_filters
triggers:
  - fetch_chart_data
  - update_url_params
initial:
  region: '"all"'
  category: '"all"'

State nodes declare:

  • fields — Typed data the state holds.
  • mutations — Named operations that can modify the state.
  • triggers — Effects that fire when this state changes.
  • initial — Default field values.

Define Effects

# graph/dashboard/effects/fetch_chart_data/effect.yaml
effect: fetch_chart_data
watch:
  - FilterState.dateRange
  - FilterState.region
handler: handlers/fetch_chart_data
effect_type: side_effect
mutates:
  - ChartState
debounce_ms: 300

Effects declare:

  • watch — State fields that trigger this effect when they change.
  • on_event — Events that trigger this effect (alternative to watch).
  • handler — Path to the handler implementation.
  • effect_typeside_effect (API calls, etc.) or derived (computed state).
  • mutates — Which state nodes this effect can write to.
  • debounce_ms — Optional debounce in milliseconds.

Define Events

# graph/dashboard/events/refresh_chart.yaml
event: refresh_chart_event
flow:
  - ChartState.set_loading
  - FilterState.reset_filters
source: ChartHeader
guards:
  - is_not_loading

Events declare:

  • flow — Ordered list of mutations to execute.
  • source — Which UI component emits this event.
  • guards — Conditions that must be true for the event to proceed.

Generate the TypeScript Runtime

Once your YAML definitions are complete, generate the runtime:

hbia ui-codegen graph/ --output hbia-runtime/

This generates:

hbia-runtime/
├── types.ts       # TypeScript interfaces from state definitions
├── store.ts       # Central pub/sub state store
├── effects.ts     # Effect watcher system
├── events.ts      # Event dispatcher
├── react.tsx      # React hooks & Provider
└── index.ts       # Re-exports

The generated runtime has:

  • No external dependencies — pure TypeScript + React hooks.
  • Pub/sub reactivity — state changes notify subscribers.
  • useSyncExternalStore — React integration via the standard React API.
  • Full auditability — every file is readable and inspectable by AI agents.

Use in React Components

import { useHBIAState, HBIAProvider } from './hbia-runtime';

// In your app root
function App() {
  return (
    <HBIAProvider>
      <Dashboard />
    </HBIAProvider>
  );
}

// In a component
function Dashboard() {
  const dateRange = useHBIAState(s => s.FilterState.dateRange);
  const loading = useHBIAState(s => s.ChartState.loading);

  // Pure render — no hooks for state management
  return (
    <div>
      {loading ? <Spinner /> : <ChartCanvas />}
    </div>
  );
}

Frontend CLI Commands

# Inspect a UI graph
hbia ui-inspect graph/dashboard/

# Show graph structure
hbia ui-graph graph/dashboard/

# Validate YAML definitions
hbia ui-validate graph/

# Lint for best practices
hbia ui-lint graph/

# Generate TypeScript runtime
hbia ui-codegen graph/ --output hbia-runtime/

Running the Full Stack

Development

# Terminal 1: Backend
cd back
uvicorn app:app --reload

# Terminal 2: Frontend
cd front
npm run dev

With Docker

docker-compose up

What's Next?

For deeper dives into each system: