How to Contribute to the Kaneo Project: Complete Contributor Guide

To contribute to the Kaneo project, fork the repository on GitHub, clone your fork locally, install dependencies with pnpm install, configure environment variables from .env.sample, and run pnpm dev to start the development servers before submitting a pull request that follows Conventional Commits and passes Biome linting and Vitest testing.

Kaneo is a self-hosted project management platform built as a pnpm monorepo with TurboRepo. Contributing to this open-source project requires understanding its three-tier architecture—Backend API, Frontend Web App, and Shared Packages—while adhering to strict code quality standards enforced through automated tooling. This guide walks you through the complete contribution workflow, from initial environment setup to merging your first pull request.

Prerequisites and System Requirements

Before contributing to Kaneo, ensure your development environment meets the following specifications defined in the root package.json:

  • pnpm ≥10 (specified in the packageManager field)
  • Node.js ≥18
  • PostgreSQL (required for running integration tests locally)

The project strictly uses Biome for code formatting with specific rules: spaces for indentation, double quotes for strings, and mandatory semicolons.

Setting Up the Local Development Environment

Follow these steps to configure your local Kaneo development environment:

  1. Fork and clone the repository:

    git clone https://github.com/<your-username>/kaneo.git
    cd kaneo
  2. Install monorepo dependencies:

    pnpm install
  3. Configure environment variables by creating .env files in both the API and Web app directories, copying from .env.sample. Required variables are documented in the root README.md and the Environment Configuration section of CLAUDE.md.

  4. Start the development servers:

    pnpm dev

    This command launches the API server on port 1337 and the Web app dev server on port 5173, accessible at http://localhost:5173.

Understanding the Kaneo Architecture

Contributing effectively requires familiarity with how the codebase is organized in pnpm-workspace.yaml.

Backend API Structure

The API resides in apps/api/ and is built with Hono (Node.js) using a controller-based pattern:

  • Database: PostgreSQL accessed via Drizzle ORM, with schema definitions centralized in apps/api/src/database/schema.ts
  • Authentication: Better Auth
  • Validation: Valibot for input sanitization
  • Documentation: OpenAPI via hono-openapi

Controllers contain business logic and are organized under apps/api/src/workspace/controllers/, keeping route definitions thin.

Frontend Web App Structure

The React 19+ application lives in apps/web/ and uses Vite for tooling:

  • Routing: TanStack Router
  • State Management: TanStack Query for server state, Zustand for client state
  • Styling: Tailwind v4 with Radix UI primitives
  • Data Fetching: Typed fetchers in apps/web/src/fetchers/ consumed by query hooks in apps/web/src/hooks/queries/

Shared Packages

Reusable code lives in packages/:

  • packages/libs/: Thin wrappers around Hono and other utilities
  • packages/mcp/: Model Context Protocol server implementation (see packages/mcp/src/server.ts)

Contribution Workflow and Standards

Finding Work

Browse the "good first issue" label on GitHub Issues or join the community Discord at https://discord.gg/rU4tSyhXXU for guidance.

Branch Naming and Commits

Create feature branches following the fix/ or feat/ naming convention:

git checkout -b fix/clear-unused-keys

All commits must follow Conventional Commits format (feat:, fix:, docs:), enforced by the pre-commit hook in .husky/pre-commit.

Code Quality Enforcement

Before submitting, run the linter and fix issues automatically:

pnpm run lint

The pre-commit hook automatically executes pnpm run build to verify the entire monorepo compiles correctly.

Testing Requirements

Validate your changes against the test suite:

  • Unit tests: pnpm test (Vitest)
  • Integration tests: pnpm test:integration (requires PostgreSQL connection)

Adding New Features: Code Examples

Creating a New API Endpoint

When adding endpoints to apps/api/src/tasks/index.ts, use the OpenAPI decorator pattern and Valibot validation:

// 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;

Business logic belongs in dedicated controllers within apps/api/src/tasks/controllers/ to maintain separation of concerns.

Adding a Frontend Query Hook

Data fetching follows a strict pattern: fetchers wrap API calls, and hooks consume them via TanStack Query:

// 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),
  });
}

The fetcher getTasks resides in apps/web/src/fetchers/tasks/get-tasks.ts and returns typed task arrays.

Implementing Localization

Kaneo uses i18next with JSON translation files stored in the i18n/ directory:

import { useTranslation } from "react-i18next";

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

Add new keys to i18n/en-US.json first, then run pnpm i18n:check:fix to propagate changes to other locale files.

Summary

  • Kaneo is a pnpm monorepo with TurboRepo requiring Node.js ≥18 and pnpm ≥10
  • Architecture splits into apps/api/ (Hono/Drizzle), apps/web/ (React/Vite), and packages/ (shared utilities)
  • Development starts with pnpm install, environment configuration, and pnpm dev for concurrent server startup
  • Code standards enforce Biome formatting, Conventional Commits, and Vitest testing via .husky/pre-commit hooks
  • Feature development follows strict patterns: controllers for API logic, fetcher/hook pairs for frontend data, and i18next keys for localization

Frequently Asked Questions

What package manager does the Kaneo project use?

The Kaneo project strictly uses pnpm version 10 or higher as specified in the packageManager field of package.json. Using npm or Yarn will result in lockfile conflicts and is not supported by the monorepo configuration.

How do I run tests before submitting a pull request?

Execute pnpm test to run unit tests with Vitest, or pnpm test:integration to run API integration tests that require a PostgreSQL database connection. These commands ensure your changes don't break existing functionality before submission.

Where are database schema changes defined?

All Drizzle ORM schema definitions live in apps/api/src/database/schema.ts, which uses CUID2 for IDs and includes timestamp utilities. When adding new tables or columns, modify this central schema file and generate migrations according to the conventions outlined in CLAUDE.md.

What happens if my code doesn't follow the formatting rules?

The Biome linter automatically enforces code style (spaces, double quotes, semicolons) through the pnpm run lint command and the .husky/pre-commit hook. If your code fails linting, the commit will be blocked until you fix the issues, either manually or by running the lint command with the --write flag.

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 →