Kaneo Project Structure Explained: A Deep Dive into the usekaneo/kaneo Monorepo
The usekaneo/kaneo project is organized as a pnpm monorepo managed by TurboRepo, with three top-level directories (apps/, packages/, charts/) containing the backend API, frontend SPA, documentation site, shared libraries, and Kubernetes deployment configuration.
Kaneo follows a modern monorepo architecture that consolidates all code, documentation, and deployment assets in a single repository. This structure, defined in pnpm-workspace.yaml, enables code sharing across applications while maintaining clear separation of concerns. Understanding the Kaneo project structure is essential for contributors and teams evaluating the codebase for self-hosted project management.
The Three Core Directories
The repository root contains three primary directories that organize all functional code:
apps/ — Runnable Applications
The apps/ directory houses three distinct applications that form the complete Kaneo platform:
- api — Backend REST API built with Hono, PostgreSQL (via Drizzle ORM), and Better Auth for authentication
- web — Frontend single-page application using React 19+, Vite, TanStack Router & Query, Tailwind CSS, Zustand, and Radix UI
- docs — Public documentation site powered by Next.js
Each app is independently deployable yet shares configuration and types through the packages/ workspace.
packages/ — Shared Libraries
The packages/ directory contains reusable modules consumed by multiple apps:
- email — Transactional email templates and sending utilities
- libs — Core TypeScript utilities imported by both API and web layers
- typescript-config — Reusable
tsconfig.jsonpresets ensuring consistent compilation across the workspace
This arrangement eliminates duplication and enforces type safety across API boundaries.
charts/ — Kubernetes Deployment
The charts/ directory includes a Helm chart (charts/kaneo/) that automates Kubernetes deployments. This enables production installations with configurable replicas, ingress rules, and secret management.
Supporting Configuration Files
Beyond the three main directories, several root-level files govern workspace behavior:
| File | Purpose |
|---|---|
pnpm-workspace.yaml |
Declares workspace packages (apps/**, packages/**) and build-time dependencies |
package.json |
Specifies pnpm as the package manager via the packageManager field; requires Node ≥ 18 |
.env |
Single source of truth for environment variables including KANEO_CLIENT_URL, KANEO_API_URL, AUTH_SECRET, and database connection strings |
CLAUDE.md |
Comprehensive contributor guide documenting monorepo patterns and code conventions |
README.md |
Quick-start guide with Docker and Kubernetes instructions |
ENVIRONMENT_SETUP.md |
Detailed variable reference for local and production configurations |
Visual Directory Layout
As documented in CLAUDE.md, the complete structure appears as:
kaneo/
├── apps/
│ ├── api/ # Backend API (Hono, Drizzle, Better Auth)
│ ├── web/ # Frontend SPA (React 19, Vite, TanStack)
│ └── docs/ # Documentation site (Next.js)
├── packages/
│ ├── email/ # Email utilities
│ ├── libs/ # Shared TypeScript libraries
│ └── typescript-config/
└── charts/ # Kubernetes Helm charts
Code Patterns Across the Monorepo
The Kaneo project structure enables consistent patterns for backend and frontend development.
Backend Route Pattern (apps/api)
API routes follow a standardized Hono setup with OpenAPI documentation and Valibot validation:
// apps/api/src/example/index.ts
import { Hono } from "hono";
import { describeRoute, validator } from "hono-openapi";
import * as v from "valibot";
import { getExample } from "./controllers/get-example";
export const example = new Hono()
.get(
"/:id",
describeRoute({
operationId: "getExample",
tags: ["Example"],
description: "Retrieve an example resource by its CUID2",
}),
validator("param", v.object({ id: v.string() })),
async (c) => {
const { id } = c.req.valid("param");
const example = await getExample(id);
return c.json(example);
},
);
This pattern appears throughout apps/api/src/ with each domain receiving its own directory containing routes, controllers, and database queries.
Frontend Integration Pattern (apps/web)
The web app consumes API endpoints through typed fetchers and TanStack Query hooks:
// apps/web/src/fetchers/example/get-example.ts
import { api } from "@/lib/api-client";
export const getExample = async (id: string) => {
const response = await api.get(`/example/${id}`);
return response.json();
};
// apps/web/src/hooks/queries/example/use-example.ts
import { useQuery } from "@tanstack/react-query";
import { getExample } from "@/fetchers/example/get-example";
export const useExample = (id: string) => {
return useQuery(["example", id], () => getExample(id));
};
The apps/web/src/routes/ directory implements file-based routing via TanStack Router, while apps/web/src/components/ houses the UI library built on Radix primitives.
Key Source Files to Know
| Path | Description |
|---|---|
apps/api/src/database/schema.ts |
Central Drizzle ORM schema defining all tables, CUID2 primary keys, and timestamp handling |
apps/web/src/routes/ |
File-based SPA route definitions |
apps/web/src/components/ |
Radix-based component library with Tailwind styling |
packages/libs/ |
Shared TypeScript utilities cross-imported by API and web |
charts/kaneo/ |
Production Helm chart for Kubernetes deployment |
Summary
- Kaneo uses a pnpm monorepo with TurboRepo orchestration, organizing code into
apps/,packages/, andcharts/directories - Three applications live in
apps/: the Hono-based API, the React/Vite frontend, and the Next.js documentation site - Shared code resides in
packages/for email, utilities, and TypeScript configuration - Single
.envfile at the repository root supplies configuration to all applications - Helm chart included at
charts/kaneo/for streamlined Kubernetes deployments - Node 18+ and pnpm required as specified in
package.json
Frequently Asked Questions
What package manager does Kaneo use?
Kaneo uses pnpm as its package manager, declared explicitly in the packageManager field of package.json. The workspace configuration in pnpm-workspace.yaml defines apps/** and packages/** as package globs. Node.js version 18 or higher is required.
How do the frontend and backend share types?
Both applications import from the packages/libs workspace package, which contains shared TypeScript utilities, types, and helper functions. This ensures API payloads and responses remain type-safe across the network boundary without code duplication.
Can I deploy Kaneo without Kubernetes?
Yes. While the charts/ directory provides a Helm chart for Kubernetes, the README.md includes Docker-based deployment instructions using docker-compose. The monorepo structure supports multiple deployment targets from the same source.
Where is the database schema defined?
All tables, relationships, and migration strategies are centralized in apps/api/src/database/schema.ts. This file uses Drizzle ORM to define the PostgreSQL schema with CUID2 primary keys and automatic timestamp handling.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →