How to Navigate the Kaneo Monorepo Structure: A Complete Guide

Kaneo is organized as a pnpm monorepo managed by TurboRepo, divided into three top-level directories—apps/ for runnable applications, packages/ for shared libraries, and charts/ for Kubernetes deployments—enabling efficient cross-package development and streamlined deployment workflows.

The usekaneo/kaneo repository follows a modern monorepo architecture designed to separate concerns between backend services, frontend interfaces, and infrastructure configuration. Understanding how to navigate the kaneo monorepo structure allows developers to quickly locate business logic, database schemas, and UI components without getting lost in nested directories. This guide breaks down the directory layout, coding patterns, and key files you need to know to contribute effectively.

Top-Level Architecture

The repository root defines the workspace in pnpm-workspace.yaml, which lists all packages and enables pnpm to resolve dependencies across the entire tree. The monorepo is partitioned into three distinct sections:

  • apps/ – Contains three runnable applications: the api (Hono backend), web (React frontend), and docs (Next.js documentation site).
  • packages/ – Houses shared libraries including email utilities, generic helper libraries, and centralized TypeScript configuration.
  • charts/ – Stores Helm charts for deploying the application stack on Kubernetes.

This separation ensures that backend engineers can work on API routes without navigating frontend React components, while DevOps teams can manage Kubernetes manifests independently of application code.

Backend Structure (apps/api)

The backend application follows a feature-based organization pattern that colocates related route handlers, controllers, and database logic.

Feature-Based Organization

Each domain feature resides in its own directory under apps/api/src/<feature>/. The entry point index.ts defines HTTP endpoints using Hono and OpenAPI decorators, while business logic is extracted to a controllers/ subdirectory. For example, a typical feature module exports routes like this:

// apps/api/src/<feature>/index.ts
import { Hono } from "hono";
import { describeRoute, validator } from "hono-openapi";
import * as v from "valibot";
import getItem from "./controllers/get-item";

const feature = new Hono<{ Variables: { userId: string } }>()
  .get("/:id",
    describeRoute({ operationId: "getItem", tags: ["Feature"], description: "Get item by ID" }),
    validator("param", v.object({ id: v.string() })),
    async (c) => {
      const { id } = c.req.valid("param");
      const item = await getItem(id);
      return c.json(item);
    }
  );

This pattern keeps route definitions declarative and delegates data access to controller functions.

Database Schema Centralization

All database tables are declared in a single source of truth at apps/api/src/database/schema.ts, which uses Drizzle ORM to define PostgreSQL schemas. Table relationships are configured separately in apps/api/src/database/relations.ts, linking entities such as user, session, and workspace. For instance, the task table definition begins at line 63 of the schema file, making it easy to locate specific table structures without searching through multiple files.

Frontend Structure (apps/web)

The apps/web/ directory mirrors the backend's organizational clarity but adapts it for a React SPA built with Vite, TanStack Router, and Tailwind CSS v4.

File-Based Routing

Routes follow a file-based convention under apps/web/src/routes/, where each folder corresponds to a URL segment. This eliminates the need for a central routing configuration file; the file system itself defines the navigation structure.

Data Fetching Patterns

Data flow is managed through TanStack Query hooks segregated by operation type. Read operations live in apps/web/src/hooks/queries/, while write operations reside in apps/web/src/hooks/mutations/. Low-level API calls are abstracted into fetcher functions located in apps/web/src/fetchers/<feature>/. A typical query hook implementation looks like this:

// apps/web/src/hooks/queries/<feature>/use-item.ts
import { useQuery } from "@tanstack/react-query";
import { getItem } from "@/fetchers/<feature>/get-item";

export function useItem(itemId: string) {
  return useQuery({
    queryKey: ["item", itemId],
    queryFn: () => getItem(itemId),
  });
}

Reusable UI components are stored in apps/web/src/components/, separate from route-specific logic and data fetching code.

Shared Packages (packages/)

Common utilities that must be imported by multiple applications live in the packages/ directory. Key packages include:

  • packages/email/ – Email sending helpers and template definitions.
  • packages/libs/ – Core shared logic, type definitions, and platform-agnostic utilities.
  • packages/typescript-config/ – Centralized tsconfig.json files referenced by all workspaces to ensure consistent compiler options.

These packages are treated as internal dependencies, allowing the API and web apps to import shared code using standard package names rather than relative paths.

Kubernetes Deployment (charts/)

Infrastructure configuration is stored under charts/kaneo/, which contains Helm charts for production deployments. The values.yaml file within this directory defines configurable parameters including image tags, resource limits, and ingress settings, enabling consistent deployment across different environments without modifying application source code.

To efficiently locate code within the kaneo monorepo structure, follow these systematic approaches:

  1. Open the workspace root – Load the repository root in your IDE; the pnpm-workspace.yaml file enables automatic resolution of cross-package imports and IntelliSense across the entire monorepo.

  2. Find backend features – Search within apps/api/src/ for the feature name. Look for an index.ts file containing Hono route definitions and an adjacent controllers/ folder containing business logic.

  3. Locate database tables – Reference apps/api/src/database/schema.ts for all table definitions. Use apps/api/src/database/relations.ts to understand foreign key relationships between entities.

  4. Trace frontend data flow – Start from the route file in apps/web/src/routes/, then follow imports to the corresponding fetcher in apps/web/src/fetchers/ and the consuming hook in apps/web/src/hooks/queries/ or hooks/mutations/.

  5. Identify shared utilities – Check packages/libs/ or packages/email/ before writing new helper functions to avoid duplication of existing logic.

Summary

  • Kaneo uses a pnpm monorepo managed by TurboRepo, defined by the root pnpm-workspace.yaml file.
  • The apps/ directory contains three distinct applications: api (Hono backend), web (React frontend), and docs (Next.js site).
  • Backend code follows a feature-based pattern with routes in apps/api/src/<feature>/index.ts and controllers in controllers/ subdirectories.
  • All database schemas are centralized in apps/api/src/database/schema.ts, with relations defined in relations.ts.
  • Frontend routing is file-based under apps/web/src/routes/, with data fetching abstracted through TanStack Query hooks in hooks/queries/ and hooks/mutations/.
  • Shared libraries reside in packages/, while Kubernetes deployment configurations are stored in charts/kaneo/.

Frequently Asked Questions

Where are the database table definitions located in the Kaneo monorepo?

All database table definitions are centralized in apps/api/src/database/schema.ts. This file uses Drizzle ORM to declare PostgreSQL tables, while foreign key relationships and entity connections are configured separately in apps/api/src/database/relations.ts.

How do I add a new API endpoint to the Kaneo backend?

Create a new folder under apps/api/src/ named after your feature. Inside, add an index.ts file to define Hono routes using describeRoute and OpenAPI decorators, then implement the business logic in a controllers/ subdirectory. Import and mount this feature in the main application entry point.

What is the purpose of the packages directory in Kaneo?

The packages/ directory contains shared libraries used by multiple applications in the monorepo. This includes packages/email/ for sending notifications, packages/libs/ for common utilities and types, and packages/typescript-config/ for shared compiler configurations, ensuring consistency across the workspace.

How does the frontend handle data fetching in the Kaneo monorepo?

The frontend uses TanStack Query for state management. Low-level API calls are defined in apps/web/src/fetchers/<feature>/, then consumed by custom hooks located in apps/web/src/hooks/queries/ for read operations and apps/web/src/hooks/mutations/ for write operations, keeping components decoupled from direct network logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →