# Kaneo Application Architecture: Main Modules and Components Explained

> Explore the Kaneo application architecture. Discover its six core modules: API Hono backend, React 19 SPA, Nextjs marketing site, MDX docs, shared packages, and Helm charts.

- Repository: [kaneo.app/kaneo](https://github.com/usekaneo/kaneo)
- Tags: architecture
- Published: 2026-08-04

---

**Kaneo is structured as a pnpm monorepo with six primary modules: API (Hono backend), Web (React 19 SPA), Site (Next.js marketing), Docs (MDX documentation), shared Packages, and Kubernetes Helm deployment charts.**

Kaneo is an open-source project management platform built with modern TypeScript tooling. Understanding the **Kaneo application modules and components** helps developers navigate the codebase, contribute effectively, and deploy custom instances. This guide breaks down each architectural layer with concrete file references from the [usekaneo/kaneo](https://github.com/usekaneo/kaneo) repository.

---

## API Backend Module

The **API module** serves as Kaneo's core HTTP service, handling all business logic, authentication, and database operations.

### Technology Stack

- **Hono** – lightweight, edge-compatible web framework
- **Valibot** – schema validation for incoming requests
- **Drizzle ORM** – type-safe PostgreSQL access
- **Better Auth** – JWT-based authentication

### Directory Organization

Located in `apps/api/src`, the backend follows feature-based grouping:

```

apps/api/src/
├── config/          # Environment, CORS, middleware setup

├── auth.ts          # Better Auth integration

├── database/
│   ├── schema.ts    # All table definitions with CUID2 IDs

│   └── migrate.ts   # Auto-run migrations

├── workspace/       # Workspace CRUD operations

├── label/           # Issue label management

├── billing/         # Creem payment integration

├── activity/        # Audit logging

├── plugins/         # GitHub, Gitea integrations

└── ws/              # WebSocket real-time layer

```

### Request Validation Example

Controllers use `hono-openapi` decorators for automatic documentation generation:

```typescript
// apps/api/src/workspace/controllers/create-workspace.ts
import { Hono } from "hono";
import { validator } from "hono-openapi";
import * as v from "valibot";

export const createWorkspaceHandler = new Hono()
  .post(
    "/",
    validator(
      "json",
      v.object({
        name: v.string(),
        slug: v.optional(v.string()),
      })
    ),
    async (c) => {
      const { name, slug } = c.req.valid("json");
      const workspace = await createWorkspace({ name, slug });
      return c.json(workspace, 201);
    }
  );

```

The `describeRoute` decorator (not shown above but used throughout) feeds OpenAPI spec generation consumed by the Docs module.

---

## Web Frontend Module

The **Web module** is Kaneo's primary user interface—a React 19 single-page application delivering the project management experience.

### Technology Stack

- **TanStack Router** – file-based routing with type safety
- **TanStack Query** – server state fetching and caching
- **Zustand** – lightweight local state management
- **Tailwind CSS v4** – utility-first styling

### Directory Structure

```

apps/web/src/
├── routes/              # File-based route tree

│   ├── _layout.tsx      # Root layout wrapper

│   ├── dashboard.tsx
│   └── projects/
│       └── $projectId.tsx
├── hooks/
│   └── queries/         # TanStack Query hooks

│       └── workspace/
│           └── use-get-workspaces.ts
├── fetchers/            # Thin API wrappers

├── store/               # Zustand stores

│   ├── project.ts       # Current project context

│   ├── preference.ts    # User settings

│   └── bulk-selection.ts
├── lib/                 # Utilities and helpers

└── components/          # UI primitives

```

### Data Fetching Pattern

Custom hooks wrap TanStack Query for consistent server state access:

```typescript
// apps/web/src/hooks/queries/workspace/use-get-workspaces.ts
import { useQuery } from "@tanstack/react-query";
import { getWorkspaces } from "@/fetchers/workspace";

export function useGetWorkspaces() {
  return useQuery({
    queryKey: ["workspaces"],
    queryFn: getWorkspaces,
  });
}

```

The fetcher layer ([`apps/web/src/fetchers/workspace/get-workspaces.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/web/src/fetchers/workspace/get-workspaces.ts)) provides thin wrappers around standard `fetch` calls, keeping components decoupled from API specifics.

---

## Site Marketing Module

The **Site module** (`apps/site`) is a separate Next.js application handling marketing pages, landing content, and user onboarding flows. This separation keeps the main Web app lightweight while allowing SEO-optimized static generation for public-facing content.

---

## Documentation Module

The **Docs module** (`apps/docs`) generates static documentation from MDX sources. It exposes:

- API reference generated from OpenAPI specs
- Deployment guides
- Usage tutorials

This module uses Next.js for static site generation and is integrated with the API's `describeRoute` decorators to ensure documentation stays synchronized with code changes.

---

## Shared Packages Module

The **Packages module** (`packages/`) contains cross-cutting libraries reused throughout the monorepo:

- **Email utilities** – templating and delivery helpers
- **TypeScript configuration** – shared [`tsconfig.json`](https://github.com/usekaneo/kaneo/blob/main/tsconfig.json) presets
- **Generic helpers** – validation utilities, type guards

Extracting these prevents duplication and enforces consistency across apps.

---

## Deployment and Infrastructure

### Kubernetes Helm Charts

Production deployment is defined in `charts/kaneo/`, with [`charts/kaneo/templates/deployment.yaml`](https://github.com/usekaneo/kaneo/blob/main/charts/kaneo/templates/deployment.yaml) specifying container orchestration for the full stack.

### Real-Time Infrastructure

The WebSocket layer (`apps/api/src/ws/`) supports horizontal scaling through pluggable broadcast adapters:

```typescript
// apps/api/src/ws/index.ts
import { InMemoryBroadcastAdapter } from "./in-memory-broadcast-adapter";

export const wsApp = new Hono()
  .get("/ws", (c) => {
    const socket = c.env.WS.accept();
    socket.addEventListener("message", async (msg) => {
      await InMemoryBroadcastAdapter.broadcast(msg.data);
    });
    return new Response(null, { status: 101 });
  });

```

Production deployments swap `InMemoryBroadcastAdapter` for a Redis-backed implementation to distribute messages across multiple API instances.

---

## Database and Schema Design

All tables in [`apps/api/src/database/schema.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/database/schema.ts) share common conventions:

- **CUID2** identifiers for globally unique, collision-resistant IDs
- **`createdAt`** and **`updatedAt`** timestamps on every table
- Foreign key constraints with cascading rules appropriate to each relationship

Migrations run automatically when the API starts, simplifying deployment workflows.

---

## Summary

- **pnpm monorepo structure** cleanly separates API, Web, Site, Docs, Packages, and deployment concerns
- **Hono-based API** in `apps/api/src` uses feature folders, Valibot validation, and Drizzle ORM with PostgreSQL
- **React 19 SPA** in `apps/web/src` leverages TanStack Router, TanStack Query, and Zustand for modern state management
- **Real-time WebSocket** support with swappable broadcast adapters for scaling
- **Helm charts** in `charts/kaneo/` provide production-ready Kubernetes deployment
- **Better Auth integration** handles JWT-based authentication across all modules

---

## Frequently Asked Questions

### What framework does Kaneo use for its backend API?

Kaneo's API is built with **Hono**, a lightweight, edge-compatible web framework. It's paired with **Valibot** for request validation, **Drizzle ORM** for database access, and **Better Auth** for authentication. The main entry point and configuration reside in [`apps/api/src/config/index.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/config/index.ts).

### How does Kaneo handle real-time updates?

Kaneo implements WebSocket support in `apps/api/src/ws/` with an abstraction layer ([`broadcast-adapter.ts`](https://github.com/usekaneo/kaneo/blob/main/broadcast-adapter.ts)) that supports both in-memory and Redis-backed broadcasting. This allows single-instance development while enabling horizontal scaling in production through the Redis adapter.

### What state management solution does the Kaneo frontend use?

The Web frontend uses **Zustand** for local state management, with dedicated stores in `apps/web/src/store/` handling project context, user preferences, and bulk selection states. Server state is managed separately through **TanStack Query** hooks defined in `apps/web/src/hooks/queries/`.

### Where are Kaneo's database schema definitions located?

All table definitions are centralized in [`apps/api/src/database/schema.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/database/schema.ts), using Drizzle ORM's type-safe schema builder. Every table uses CUID2 IDs and includes `createdAt`/`updatedAt` timestamps for audit purposes.