# How to Contribute to the Usekaneo/Kaneo Project: A Complete Guide

> Learn how to contribute to the usekaneo/kaneo project. Understand its pnpm monorepo, backend/frontend patterns, and coding standards to make your first contribution.

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

---

**The Kaneo contribution process requires understanding its pnpm monorepo architecture, following established patterns for backend controllers and frontend hooks, and adhering to Biome formatting and Conventional Commits standards.**

Kaneo is a **self-hosted project management platform** built as a modern TypeScript monorepo. Whether you want to fix a bug, add a feature, or improve documentation, this guide walks you through exactly how to contribute to Kaneo based on the actual source code structure.

## Understanding Kaneo's Architecture

Before writing code, you need to understand how Kaneo is organized. The repository uses **pnpm workspaces** with three distinct layers:

| Layer | Technology Stack | Location |
|---|---|---|
| **API (backend)** | Hono, Drizzle ORM, Better Auth, Valibot, PostgreSQL | `apps/api/` |
| **Web (frontend)** | React 19+, TanStack Router, TanStack Query, Zustand, Radix UI, Tailwind CSS v4 | `apps/web/` |
| **Shared packages** | Reusable utilities and types | `packages/` |

The build system uses **TurboRepo** ([`turbo.json`](https://github.com/usekaneo/kaneo/blob/main/turbo.json)) to orchestrate tasks across all packages. Everything is containerized with Docker and deployable via Helm charts in `charts/kaneo/`.

## Setting Up Your Development Environment

Follow these steps to get Kaneo running locally:

1. **Fork and clone** the repository from `github.com/usekaneo/kaneo`.

2. **Install dependencies** with pnpm:

```bash
pnpm install

```

3. **Configure environment variables** by copying `.env.sample` to `.env`, then follow [`ENVIRONMENT_SETUP.md`](https://github.com/usekaneo/kaneo/blob/main/ENVIRONMENT_SETUP.md) for database setup, CORS configuration, and other requirements.

4. **Start development servers**:

```bash
pnpm dev

```

5. **Verify your setup** by running the test suite:

```bash
pnpm test
pnpm test:integration

```

The CI pipeline defined in [`.github/workflows/ci.yml`](https://github.com/usekaneo/kaneo/blob/main/.github/workflows/ci.yml) will run these same checks on your pull request, so pass them locally first.

## Contributing to the Backend (API)

Backend code lives in `apps/api/` and follows a **controller pattern** with OpenAPI documentation.

### Adding a New API Endpoint

Create a controller in `apps/api/src/<feature>/controllers/`, then expose it through a feature module:

```typescript
// apps/api/src/status/controllers/get-status.ts
export async function getStatus() {
  return { status: "🟢 Kaneo is running!" };
}

```

```typescript
// apps/api/src/status/index.ts
import { Hono } from "hono";
import { describeRoute } from "hono-openapi";
import { getStatus } from "./controllers/get-status";

export const status = new Hono()
  .get(
    "/",
    describeRoute({
      operationId: "getStatus",
      tags: ["Status"],
      description: "Health check endpoint",
    }),
    async (c) => c.json(await getStatus())
  );

```

### Key Backend Files to Know

- **[`apps/api/src/database/schema.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/database/schema.ts)** — Central Drizzle ORM schema definition
- **[`apps/api/src/database/relations.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/database/relations.ts)** — Foreign key and cascade rule mappings
- **[`apps/api/vitest.config.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/vitest.config.ts)** — Test configuration

All request validation uses **Valibot** schemas. Authentication is handled by **Better Auth** middleware.

## Contributing to the Frontend (Web)

Frontend code lives in `apps/web/` and follows a strict **data-fetching pattern**: fetchers → hooks → components.

### Creating a Data Fetcher

First, create a fetcher function:

```typescript
// apps/web/src/fetchers/status/get-status.ts
export async function getStatus() {
  const res = await fetch(`${import.meta.env.VITE_API_URL}/status`);
  return res.json();
}

```

### Exposing via TanStack Query

Wrap the fetcher in a query hook:

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

export function useStatus() {
  return useQuery(["status"], getStatus);
}

```

For mutations, place hooks in `apps/web/src/hooks/mutations/` instead.

### Building UI Components

Consume hooks in React components:

```tsx
// apps/web/src/components/StatusBadge.tsx
export function StatusBadge() {
  const { data, isLoading } = useStatus();

  if (isLoading) return <span>Loading…</span>;
  return <span>{data?.status}</span>;
}

```

### Key Frontend Directories

- **`apps/web/src/fetchers/`** — API interaction functions
- **`apps/web/src/hooks/queries/`** — TanStack Query read hooks
- **`apps/web/src/hooks/mutations/`** — TanStack Query write hooks
- **`apps/web/src/components/`** — Reusable UI components

State management uses **Zustand** for global state and **TanStack Query** for server state. UI components build on **Radix UI** primitives with **Tailwind CSS v4** styling.

## Contributing to Shared Packages

Reusable code belongs in `packages/` and is imported via the **`@/` alias** throughout the codebase. For example, email utilities live in `packages/email/`. When adding shared code:

1. Create or use an appropriate package under `packages/`
2. Export from the package's [`index.ts`](https://github.com/usekaneo/kaneo/blob/main/index.ts)
3. Import elsewhere using `@/package-name`

## Code Standards and Quality

Kaneo enforces strict consistency through automated tooling:

| Tool | Purpose | Configuration |
|---|---|---|
| **Biome** | Formatting and linting | Double quotes, semicolons, import ordering |
| **Conventional Commits** | Git history structure | `feat:`, `fix:`, `docs:`, `refactor:` prefixes |
| **TurboRepo** | Build pipeline | Defined in [`turbo.json`](https://github.com/usekaneo/kaneo/blob/main/turbo.json) |

Before committing, run:

```bash
pnpm lint
pnpm format

```

The CI pipeline will reject PRs that fail these checks.

## Testing Your Contributions

Kaneo has two test suites:

- **Unit tests**: `tests/api/` — fast, isolated tests for business logic
- **Integration tests**: `tests/api-integration/` — full request/response cycles

Add tests alongside your code changes. The existing patterns in these directories show how to structure them.

## Submitting Your Contribution

1. **Branch** from `main` with a descriptive name: `feat/status-endpoint` or `fix/auth-redirect`.

2. **Commit** using Conventional Commits:
   - `feat: add health check endpoint`
   - `fix: correct redirect after login`
   - `docs: update API authentication section`

3. **Push** to your fork and open a Pull Request against `usekaneo/kaneo/main`.

4. **Verify CI passes** — the pipeline in [`.github/workflows/ci.yml`](https://github.com/usekaneo/kaneo/blob/main/.github/workflows/ci.yml) runs lint, build, and all tests.

Review [`CONTRIBUTING.md`](https://github.com/usekaneo/kaneo/blob/main/CONTRIBUTING.md) in the repository for any additional requirements.

## Summary

- Kaneo is a **pnpm monorepo** with separate `apps/api/`, `apps/web/`, and `packages/` directories
- Backend contributions use **Hono controllers** with **Valibot validation** and **OpenAPI documentation**
- Frontend contributions follow a **fetcher → hook → component** pattern using **TanStack Query**
- All code must pass **Biome** formatting and use **Conventional Commits**
- The **TurboRepo** build system and **CI pipeline** validate every change automatically

## Frequently Asked Questions

### What programming languages does Kaneo use?

Kaneo is built entirely in **TypeScript**. The backend uses **Hono** (a lightweight web framework), and the frontend uses **React 19+** with modern tooling including TanStack Router, TanStack Query, and Tailwind CSS v4.

### Do I need to know the entire codebase to contribute?

No. Kaneo's architecture is deliberately layered, so you can contribute to just the **API**, **web frontend**, or **shared packages** independently. Start with one layer and follow the established patterns in that area.

### How do I test my changes before submitting a PR?

Run `pnpm test` for unit tests and `pnpm test:integration` for integration tests. The CI pipeline defined in [`.github/workflows/ci.yml`](https://github.com/usekaneo/kaneo/blob/main/.github/workflows/ci.yml) runs these same commands, so passing locally ensures your PR will pass automated checks.

### Where can I find the official contribution guidelines?

The [`CONTRIBUTING.md`](https://github.com/usekaneo/kaneo/blob/main/CONTRIBUTING.md) file in the repository root contains authoritative guidelines for coding standards, PR workflow, and community expectations. For environment setup details, see [`ENVIRONMENT_SETUP.md`](https://github.com/usekaneo/kaneo/blob/main/ENVIRONMENT_SETUP.md).