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

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) 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:

pnpm install
  1. Configure environment variables by copying .env.sample to .env, then follow ENVIRONMENT_SETUP.md for database setup, CORS configuration, and other requirements.

  2. Start development servers:

pnpm dev
  1. Verify your setup by running the test suite:
pnpm test
pnpm test:integration

The CI pipeline defined in .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:

// apps/api/src/status/controllers/get-status.ts
export async function getStatus() {
  return { status: "🟢 Kaneo is running!" };
}
// 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

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:

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

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

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

Before committing, run:

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 runs lint, build, and all tests.

Review 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 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 file in the repository root contains authoritative guidelines for coding standards, PR workflow, and community expectations. For environment setup details, see ENVIRONMENT_SETUP.md.

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 →