Skip to main content

Architecture Overview

Project AIRI is built as a modern, modular monorepo designed to power AI-driven virtual characters across multiple platforms. This guide provides a comprehensive overview of the system architecture, technology stack, and component interactions.

System Architecture

AIRI follows a layered architecture that separates concerns between presentation (Stage), business logic (Core), and runtime services (Server).

Monorepo Structure

The project is organized as a pnpm workspace monorepo with clear separation of concerns:

Directory Layout

Workspace Organization

Application-level packages that users interact with directly:
  • stage-web: Browser-based web application (Vue 3 + Vite)
  • stage-tamagotchi: Desktop application (Electron + Vue 3)
  • stage-pocket: Mobile application (Capacitor + Vue 3)
  • server: Backend API server
  • component-calling: Component system examples

Technology Stack

Frontend Technologies

Backend & Runtime Technologies

Development Tools

Key Libraries

  • @xsai/generate-text: Text generation abstraction
  • @xsai/stream-text: Streaming text generation
  • @xsai/generate-speech: Speech synthesis
  • @xsai/stream-transcription: Streaming speech recognition
  • @huggingface/transformers: Transformers.js for in-browser ML
  • onnxruntime-web: ONNX model inference in browser
  • @moeru/eventa: Type-safe IPC/RPC framework
  • injeca: Dependency injection for services
  • crossws: WebSocket server/client
  • superjson: JSON serialization with type preservation
  • @tresjs/core: Three.js Vue integration
  • @tresjs/cientos: Three.js helper components
  • animejs: Animation library
  • @vueuse/motion: Vue animation composables
  • valibot: Schema validation
  • zod: Alternative schema validation
  • xstate: State machine library

Frontend Architecture

Stage Applications

The “Stage” represents the presentation layer where AIRI appears to users. All Stage applications share a common architecture:

Component Hierarchy

Stage UI Package (packages/stage-ui/)

The heart of the Stage system, containing: Directory Structure:
Key Responsibilities:
  • Character state management
  • Provider configurations (OpenAI, Claude, etc.)
  • Audio input/output handling
  • Speech recognition (VAD)
  • UI business logic
  • Animation controllers

UI Primitives (packages/ui/)

Standardized UI primitives built on reka-ui:
  • Form components (Input, Textarea, Select, etc.)
  • Layout components (Card, Dialog, Sheet, etc.)
  • Feedback components (Toast, Alert, etc.)
  • Minimal business logic - pure presentation

Styling System

AIRI uses UnoCSS (not Tailwind) for styling. Prefer UnoCSS over Tailwind CSS throughout the codebase.
Best Practices:
Configuration:
  • Main config: uno.config.ts at root
  • Custom shortcuts and rules defined in config
  • Theme customization via UnoCSS presets

Routing

Router configuration in vite.config.ts:
Pages directory: apps/stage-web/src/pages/ Devtools: apps/stage-web/src/pages/devtools/
Route Layouts: Settings and devtools routes use layout metadata:

Backend Architecture

Server Runtime (packages/server-runtime/)

The server runtime provides a WebSocket-based communication layer for connecting various AIRI components.

Architecture

Key Concepts

Peers: Connected WebSocket clients (UI, plugins, services) Modules: Named components that announce themselves Events: Messages with metadata, routing info, and data Routing: Event forwarding with destination filtering

Event Types

Running the Server

Server SDK (packages/server-sdk/)

Client SDK for connecting to the server runtime:

Data Flow

User Interaction Flow

Plugin Communication Flow

IPC & Communication

Eventa Framework

AIRI uses @moeru/eventa for type-safe, framework-agnostic IPC/RPC:
Usage Locations:
  • Electron main ↔️ renderer: apps/stage-tamagotchi/src/shared
  • Plugin ↔️ host: packages/plugin-sdk
  • Service ↔️ service: Custom contracts

Dependency Injection

AIRI uses injeca for dependency injection:
Usage Pattern: See apps/stage-tamagotchi/src/main/index.ts for composition patterns.

Database & Persistence

DuckDB WASM

In-browser database for web and desktop:

Storage Solutions

Internationalization

Centralized translations in packages/i18n/:
Adding Translations:
  1. Add keys to packages/i18n/locales/
  2. Never scatter i18n across apps/packages
  3. Contribute to Crowdin for translations

Performance Considerations

Web Performance

Web Workers

VAD and heavy computations run in Web Workers to avoid blocking the main thread.

Code Splitting

Dynamic imports and route-based splitting reduce initial bundle size.

WebGPU

GPU acceleration for ML inference and 3D rendering where available.

WASM

DuckDB and ONNX Runtime use WebAssembly for near-native performance.

Desktop Performance

The Electron app (stage-tamagotchi) can use:
  • Native CUDA (NVIDIA)
  • Metal (Apple)
  • Native file system access
  • Native audio/video APIs

Mobile Performance

Capacitor (stage-pocket) bridges to native APIs:
  • Native camera/microphone
  • Push notifications
  • Background tasks
  • File system access

Build System

Turbo Orchestration

The monorepo uses Turbo for efficient builds:

Package Bundling

Packages use tsdown for bundling:

Testing Strategy

Unit Tests (Vitest)

Testing Patterns

Guidelines:
  • Mock IPC/services with vi.fn()/vi.mock()
  • Don’t rely on real Electron runtime
  • Keep tests targeted for speed
  • Use Vitest browser env where possible

Configuration Files

Key Configuration Locations

Environment Variables

Common environment variables:

Next Steps

Plugin Development

Learn how to create plugins for AIRI

Contributing Guide

Set up your development environment

API Reference

Explore the API documentation

Examples

Check out example implementations