# Best Practices for Developing with holaOS: A Complete Guide to the Monorepo Architecture

> Master holaOS development with our guide to monorepo best practices. Learn wrapper patterns, ordered migrations, and agent architecture for efficient building.

- Repository: [holaboss.ai/holaOS](https://github.com/holaboss-ai/holaOS)
- Tags: best-practices
- Published: 2026-08-15

---

**TLDR:** holaOS development follows strict conventions across its Electron desktop app, TypeScript runtime, state store, and plugin SDK—use wrapper patterns for UI components, ordered migrations for database changes, skill-based architecture for agent capabilities, and provided npm scripts for reproducible builds.

holaOS is a monorepo that combines a desktop **Electron front-end**, a **TypeScript runtime**, a **plug-in SDK**, and agent-invokable **skills**. Following established best practices for developing with holaOS ensures your contributions remain type-safe, testable, and compatible with the automated CI pipeline. This guide covers the architectural conventions, critical file paths, and practical patterns used throughout the codebase according to the holaboss-ai/holaOS source.

## Desktop App Development Practices

The desktop application lives in `apps/desktop/` and serves as the Electron wrapper that loads the runtime bundle and renders **HolaApps**.

### Use Provided npm Scripts for Reproducible Workflows

Never run Electron directly. The repository provides standardized scripts:

```bash

# Initial setup

npm run desktop:install

# Prepare runtime with local state store

npm run desktop:prepare-runtime:local

# Start development server

npm run desktop:dev

```

These scripts handle bundling, environment validation, and runtime initialization in the correct order.

### Environment Configuration

Copy the template before first run:

```bash
cp apps/desktop/.env.example apps/desktop/.env

```

Keep all environment-specific variables in `apps/desktop/.env`. The `.env.example` file documents required keys for new developers.

### Icon Wrapper Pattern (Critical)

**Never import icons directly from `lucide-react` or `@hugeicons/core-free-icons`.** All UI icons must route through the centralized wrapper:

```tsx
// apps/desktop/src/components/ui/icons.tsx
import { makeIcon } from '@hugeicons/core-free-icons';
import { IconType } from '@hugeicons/core-free-icons';

export const MyNewIcon: IconType = makeIcon(
  <svg viewBox="0 0 24 24"><path d="M12 2l7 7h-4v7h-6V9H5z"/></svg>
);

```

```tsx
// Correct usage in components
import { MyNewIcon } from '@/components/ui/icons';

export default function Sidebar() {
  return <MyNewIcon className="w-5 h-5" />;
}

```

Direct imports trigger CI lint errors as documented in [`AGENTS.md`](https://github.com/holaboss-ai/holaOS/blob/main/AGENTS.md). The wrapper enforces consistent sizing, styling, and tree-shaking behavior.

## Runtime State Store Management

The state store at [`runtime/state-store/src/store.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/state-store/src/store.ts) provides **durable, file-based storage** for shared memory, sessions, and agent capabilities.

### Migration-Driven Schema Changes

Always use numbered migration files:

```ts
// runtime/state-store/src/migrations/034-add-notifications.ts
import { Migration } from '../migrations';

export const migration034: Migration = {
  id: 34,
  up: async (db) => {
    await db.exec(`
      CREATE TABLE notifications (
        id TEXT PRIMARY KEY,
        message TEXT NOT NULL,
        created_at INTEGER NOT NULL
      );
    `);
  },
};

```

Key practices:
- **Keep migrations ordered numerically** (001-, 002-, etc.)
- **Run migrations before launch**: `npm run desktop:prepare-runtime`
- **Write unit tests**: See [`src/migrations.test.ts`](https://github.com/holaboss-ai/holaOS/blob/main/src/migrations.test.ts) for the test pattern

## Harness and Skill Development

The harness system in `runtime/harnesses/src/` exposes tools, model routing, and **MCP (Model Context Protocol)** to agents.

### Skill-Based Architecture

Implement new capabilities as **skills** under `runtime/harnesses/src/embedded-skills/`:

```ts
// runtime/harnesses/src/embedded-skills/my-api-client/SKILL.ts
import { createSkill } from '../skill-base';
import { fetch } from 'node-fetch';

export const myApiSkill = createSkill('myApiClient', async (input) => {
  const resp = await fetch(`https://api.example.com/v1/${input.id}`);
  const data = await resp.json();
  return data;
});

```

Required steps:
1. Follow the template in [`runtime/harnesses/src/embedded-skills/SKILL.md`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/embedded-skills/SKILL.md)
2. Register the skill in [`runtime/harnesses/src/index.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/index.ts)
3. Add unit tests at `runtime/harnesses/src/embedded-skills/[skill-name]/SKILL.test.ts`
4. Update `interface-design` documentation

### Tool Usage Tracking

Use the **`tool-replay-budget-ledger`** to monitor and enforce tool usage limits for agents.

## Plugin SDK Integration

The **app-builder-sdk** (`packages/app-builder-sdk`) provides type-safe wrappers for HolaApps running inside the workspace.

### SDK Generation and Synchronization

Generate SDK updates from the OpenAPI specification:

```bash
npm run generate:sdk

```

This uses **Kubb** to produce type-safe clients. Always:
- Keep SDK version synchronized with server contract
- Verify against [`packages/app-builder-sdk/README.md`](https://github.com/holaboss-ai/holaOS/blob/main/packages/app-builder-sdk/README.md) before releasing

## Build and Bundle Configuration

holaOS uses **tsup**, **vite**, and **tsdown** for bundling. Follow existing patterns:

```ts
// runtime/state-store/tsup.config.ts - reference implementation
import { defineConfig } from 'tsup';

export default defineConfig({
  entry: ['src/index.ts'],
  format: ['cjs', 'esm'],
  dts: true,
  splitting: false,
  sourcemap: true,
  clean: true,
});

```

Always run `npm run build` in each package before committing to ensure clean output and type generation.

## Testing and CI Requirements

- Run `npm test` locally before pushing—this executes Jest unit tests and Playwright integration tests
- Add tests for any public API change
- Mirror patterns from [`runtime/state-store/src/store.test.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/state-store/src/store.test.ts)

## Documentation and Versioning

### Keep Docs Synchronized

Documentation lives in `docs/` and `contribute/`. Update relevant files when changing code:
- [`plugin-sdk.md`](https://github.com/holaboss-ai/holaOS/blob/main/plugin-sdk.md) for SDK method additions
- [`SKILL.md`](https://github.com/holaboss-ai/holaOS/blob/main/SKILL.md) when modifying skill interfaces
- [`AGENTS.md`](https://github.com/holaboss-ai/holaOS/blob/main/AGENTS.md) for agent behavior changes

### Conventional Commits

Drive changelogs with structured commits:

```

feat: add notification polling to runtime

- Implements webhook fallback for missed events
- Adds retry logic with exponential backoff
- Updates SKILL.md with new error handling pattern

```

Prefixes: `feat:`, `fix:`, `chore:`, `docs:`, `test:`

## Summary

- **Desktop workflow**: Use provided npm scripts, `.env` configuration, and the icon wrapper pattern in [`apps/desktop/src/components/ui/icons.tsx`](https://github.com/holaboss-ai/holaOS/blob/main/apps/desktop/src/components/ui/icons.tsx)
- **State store**: Create ordered migrations, run `desktop:prepare-runtime`, and test each migration
- **Skills**: Build agent capabilities using the [`SKILL.md`](https://github.com/holaboss-ai/holaOS/blob/main/SKILL.md) template in `runtime/harnesses/src/embedded-skills/`
- **SDK**: Generate from OpenAPI with `generate:sdk` and keep versions synchronized
- **Build**: Follow existing [`tsup.config.ts`](https://github.com/holaboss-ai/holaOS/blob/main/tsup.config.ts) patterns and build before commit
- **Quality**: Test locally with `npm test`, use conventional commits, and synchronize documentation

## Frequently Asked Questions

### What is the holaOS monorepo structure?

holaOS combines four main components: an Electron desktop app (`apps/desktop/`), a TypeScript runtime with state store (`runtime/state-store/`), agent harnesses with MCP support (`runtime/harnesses/`), and a plugin SDK (`packages/app-builder-sdk`). These share a unified build system and testing infrastructure.

### Why can't I import icons directly from icon libraries?

Direct imports from `lucide-react` or `@hugeicons/core-free-icons` bypass the centralized `makeIcon` wrapper in [`apps/desktop/src/components/ui/icons.tsx`](https://github.com/holaboss-ai/holaOS/blob/main/apps/desktop/src/components/ui/icons.tsx). This breaks styling consistency, tree-shaking optimization, and CI lint rules. The wrapper enforces uniform behavior across all UI components.

### How do I add a new database table to holaOS?

Create a numbered migration file in `runtime/state-store/src/migrations/`, implement the `Migration` interface with `up` and `down` methods, add a corresponding test file, then run `npm run desktop:prepare-runtime:local` to apply it. Never modify existing migration files once committed.

### What is MCP in holaOS and where is it implemented?

**MCP (Model Context Protocol)** enables plugging in any LLM provider or custom tool server to agent harnesses. The core client implementation lives in [`runtime/harnesses/src/mcp.ts`](https://github.com/holaboss-ai/holaOS/blob/main/runtime/harnesses/src/mcp.ts), allowing agents to route requests to external models or specialized tool servers through a standardized interface.