# How to Contribute to the Kaneo Project: A Complete Developer Guide

> Learn how to contribute to the Kaneo project. Fork the repo, install dependencies, set up env vars, branch, and submit a PR. Your guide to open source development.

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

---

**To contribute to Kaneo, fork the repository, install dependencies with pnpm, configure environment variables from `.env.sample`, create a feature branch using the `feat/` or `fix/` prefix, and submit a pull request after passing local tests and the Biome linter.**

Kaneo is a self-hosted project management platform built as a **pnpm monorepo** with TurboRepo. Contributing to the kaneo project involves working across a Hono-based backend API and a React 19+ frontend, following strict conventions for code style, testing, and commit messages. This guide walks you through the complete development workflow, from cloning the repository to merging your changes.

## Prerequisites and Monorepo Structure

Before you begin contributing to Kaneo, ensure your environment meets the requirements defined in [`package.json`](https://github.com/usekaneo/kaneo/blob/main/package.json):

- **Node.js** ≥ 18
- **pnpm** ≥ 10 (enforced via the `packageManager` field)

The repository is organized as a TurboRepo monorepo with three distinct areas:

- **`apps/api/`** – Hono backend with PostgreSQL (via Drizzle ORM), Better Auth authentication, and Valibot validation
- **`apps/web/`** – React 19+ frontend using Vite, TanStack Router, TanStack Query, Zustand, and Tailwind v4
- **`packages/`** – Shared utilities including `packages/libs` (Hono wrappers) and `packages/mcp` (Model-Context-Protocol server implementation)

## Setting Up Your Local Development Environment

Follow these steps to configure your local instance of the kaneo project:

1. **Fork and clone** the repository:

   ```bash
   git clone https://github.com/<your-username>/kaneo.git
   cd kaneo
   ```

2. **Install dependencies** using pnpm:

   ```bash
   pnpm install
   ```

3. **Configure environment variables** by copying `.env.sample` to `.env` in both the API and Web application roots. Required variables are documented in the root [`README.md`](https://github.com/usekaneo/kaneo/blob/main/README.md) and the Environment Configuration section of [`CLAUDE.md`](https://github.com/usekaneo/kaneo/blob/main/CLAUDE.md).

4. **Start the development servers**:

   ```bash
   pnpm dev
   ```

   This command launches the API on port 1337 and the Web app on port 5173. The frontend will automatically proxy requests to the backend.

## Contribution Workflow Standards

When contributing to the kaneo project, adhere to these Git and workflow conventions:

### Branch Naming and Commit Messages

Create feature branches using the prefixes `feat/` or `fix/`:

```bash
git checkout -b fix/clear-unused-keys

```

The project enforces **Conventional Commits** (e.g., `feat:`, `fix:`, `docs:`) via a pre-commit hook. Write messages that clearly describe the change:

```bash
git commit -m "fix: remove stale translation keys"

```

### Finding Work and Getting Help

Browse the [GitHub issues](https://github.com/usekaneo/kaneo/issues) filtered by the "good first issue" label for beginner-friendly tasks. For real-time guidance, join the community Discord at `https://discord.gg/rU4tSyhXXU`.

## Backend Development Patterns

The Kaneo API in `apps/api/` follows a controller pattern with OpenAPI documentation.

### Adding a New API Endpoint

Create routes in `apps/api/src/<feature>/index.ts` and delegate business logic to controllers:

```typescript
// apps/api/src/tasks/index.ts
import { Hono } from "hono";
import { describeRoute, validator } from "hono-openapi";
import * as v from "valibot";
import { createTask } from "./controllers/create-task";

const tasks = new Hono()
  .post(
    "/",
    describeRoute({
      operationId: "createTask",
      tags: ["Tasks"],
      description: "Create a new task",
    }),
    validator("json", v.object({
      title: v.string(),
      projectId: v.string(),
    })),
    async (c) => {
      const { title, projectId } = c.req.valid("json");
      const task = await createTask({ title, projectId });
      return c.json(task, 201);
    },
  );

export default tasks;

```

Controllers live in `apps/api/src/<feature>/controllers/` and contain the business logic, keeping routes thin. Database schemas are defined in [`apps/api/src/database/schema.ts`](https://github.com/usekaneo/kaneo/blob/main/apps/api/src/database/schema.ts) using Drizzle ORM with CUID2 identifiers.

## Frontend Development Patterns

The web application in `apps/web/` uses TanStack Query for server state management.

### Creating Query Hooks

Define typed hooks in `apps/web/src/hooks/queries/`:

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

export function useTasks(projectId: string) {
  return useQuery({
    queryKey: ["tasks", projectId],
    queryFn: () => getTasks(projectId),
  });
}

```

Fetchers reside in `apps/web/src/fetchers/` and handle the low-level API communication. UI components are built on Radix primitives with Tailwind v4 styling.

### Localization Workflow

Kaneo uses i18next with translation keys stored in `i18n/*.json`. When adding new keys:

1. Add the key to [`i18n/en-US.json`](https://github.com/usekaneo/kaneo/blob/main/i18n/en-US.json) first
2. Run `pnpm i18n:check:fix` to propagate changes to other locales

Example usage in components:

```tsx
import { useTranslation } from "react-i18next";

export function CloseButton() {
  const { t } = useTranslation();
  return <button>{t("common:actions.close")}</button>;
}

```

## Testing and Quality Assurance

Validate your changes before submitting:

- **Unit tests**: Run `pnpm test` (Vitest)
- **Integration tests**: Run `pnpm test:integration` (requires PostgreSQL)
- **Linting**: Run `pnpm run lint` to auto-fix Biome formatting issues

The `.husky/pre-commit` hook automatically executes `pnpm run build` to verify the monorepo compiles before allowing commits.

## Submitting Your Contribution

Push your branch and open a pull request against the main repository:

```bash
git push origin fix/clear-unused-keys

```

Include a concise summary, motivation, and screenshots or test results in the PR description. Address review feedback promptly and squash commits before final merge. The CI pipeline will run the full build (`pnpm run build`) to ensure compatibility.

## Summary

- **Fork and clone** the kaneo repository, then run `pnpm install` to initialize the monorepo
- **Configure `.env`** files for both API and Web apps before starting development with `pnpm dev`
- **Follow conventions**: Use `feat/` or `fix/` branch prefixes, Conventional Commits, and Biome formatting
- **Write tests** for new features using Vitest and validate with `pnpm test`
- **Submit PRs** with clear descriptions and ensure the pre-commit build passes

## Frequently Asked Questions

### Do I need Docker to contribute to the kaneo project?

No, Docker is not required for basic development. You can run the API and Web app directly using `pnpm dev` after setting up a local PostgreSQL instance. However, Docker Compose files are available in the repository for convenient database setup if preferred.

### What happens if the build fails in CI?

The `.husky/pre-commit` hook runs `pnpm run build` locally to catch errors before pushing. If CI fails, check that all packages compile by running `pnpm run build` manually and resolve any TypeScript errors in `apps/api/` or `apps/web/` before re-pushing.

### How do I add a new translation language to Kaneo?

Add the new locale file to the `i18n/` directory following the existing JSON structure. Update the language detection logic in the web app and ensure you run `pnpm i18n:check:fix` to validate the translation keys match the schema defined in the English source files.

### Where should I place shared utility functions?

Place reusable utilities that bridge backend and frontend concerns in `packages/libs/`. For Model-Context-Protocol implementations or server-side integrations, use `packages/mcp/` as demonstrated in [`packages/mcp/src/server.ts`](https://github.com/usekaneo/kaneo/blob/main/packages/mcp/src/server.ts).