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/– Centralizedtsconfig.jsonfiles 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.
Navigation Strategies
To efficiently locate code within the kaneo monorepo structure, follow these systematic approaches:
-
Open the workspace root – Load the repository root in your IDE; the
pnpm-workspace.yamlfile enables automatic resolution of cross-package imports and IntelliSense across the entire monorepo. -
Find backend features – Search within
apps/api/src/for the feature name. Look for anindex.tsfile containing Hono route definitions and an adjacentcontrollers/folder containing business logic. -
Locate database tables – Reference
apps/api/src/database/schema.tsfor all table definitions. Useapps/api/src/database/relations.tsto understand foreign key relationships between entities. -
Trace frontend data flow – Start from the route file in
apps/web/src/routes/, then follow imports to the corresponding fetcher inapps/web/src/fetchers/and the consuming hook inapps/web/src/hooks/queries/orhooks/mutations/. -
Identify shared utilities – Check
packages/libs/orpackages/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.yamlfile. - 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.tsand controllers incontrollers/subdirectories. - All database schemas are centralized in
apps/api/src/database/schema.ts, with relations defined inrelations.ts. - Frontend routing is file-based under
apps/web/src/routes/, with data fetching abstracted through TanStack Query hooks inhooks/queries/andhooks/mutations/. - Shared libraries reside in
packages/, while Kubernetes deployment configurations are stored incharts/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →