# How to Contribute to the Lobe Chat Project: A Complete Developer Guide

> Learn how to contribute to the Lobe Chat project. Follow this developer guide to fork, clone, set up, and submit your first pull request to lobehub/lobe-chat.

- Repository: [LobeHub/lobe-chat](https://github.com/lobehub/lobe-chat)
- Tags: how-to-guide
- Published: 2026-03-03

---

**Fork the repository, clone it locally, run `pnpm install` to set up the monorepo, create a feature branch, follow the Zustand slice pattern for state management, and submit a PR against the `canary` branch after running `pnpm lint` and `bunx vitest run`.**

Contributing to the Lobe Chat project (also known as LobeHub) involves working with a modern AI-agent workspace built on Next.js 16, React 19, and TypeScript. Whether you want to fix bugs, add features, or improve documentation, understanding the monorepo structure and contribution workflow is essential for getting your pull request merged into the `lobehub/lobe-chat` repository.

## Understanding the Lobe Chat Architecture

LobeChat uses a monorepo structure managed by pnpm workspaces. The stack is organized into distinct layers:

| Layer | Technology | Primary Location |
|------|------|------------------|
| **Frontend** | Next.js 16 / React 19 / TypeScript | `src/app/*`, `src/routes/*` |
| **UI Components** | Ant Design, @lobehub/ui | `src/components/*` |
| **State Management** | Zustand, SWR | `src/store/*` |
| **Backend / DB** | PostgreSQL, PGLite, Drizzle ORM | `packages/database/*` |
| **Desktop** | Electron | `src/store/electron/*` |

### Core Architectural Patterns

The repository follows specific patterns for organizing code:

- **App entry & routing**: `src/app/**` and `src/routes/**` contain Next.js App Router definitions, including page-level routes like the share page at `src/routes/share/t/[id]/index.tsx`.

- **State slices**: `src/store/*/slices/*` isolates each feature (video generation, evaluation, user memory) into composable Zustand slices.

- **Electron integration**: `src/store/electron/**` bridges the web UI with desktop runtime via IPC, hotkeys, and desktop state management.

- **Server-side utilities**: `src/utils/server/**` provides helpers for parsing model lists and routing variants used by the Next.js API layer.

## Setting Up Your Development Environment

Before contributing to the Lobe Chat project, ensure you have the prerequisites installed:

- **Node.js** ≥ 18
- **pnpm** (package manager)
- **git**

### Initial Setup Steps

1. Fork the repository on GitHub to create your personal copy.

2. Clone your fork locally:

   ```bash
   git clone https://github.com/<YOUR_USERNAME>/lobe-chat.git
   cd lobe-chat
   ```

3. Install dependencies using pnpm workspaces:

   ```bash
   pnpm install
   ```

## The Contribution Workflow

Follow this canonical process when contributing to Lobe Chat:

### 1. Create a Feature Branch

```bash
git checkout -b feature/your-feature-name

```

### 2. Develop and Lint

The codebase follows strict ESLint and Prettier rules. Run the linter to catch style issues early:

```bash
pnpm lint

```

When adding features involving state management, follow the existing Zustand slice pattern. For example, adding a new feature would involve editing `src/store/<feature>/slices/*` and updating the combined reducer in `src/store/<feature>/index.ts`.

### 3. Write Tests

New logic should include unit tests under `src/**/*.test.*`. Run the test suite:

```bash
bunx vitest run

```

### 4. Commit Changes

Use clear, conventional commit messages. The project encourages gitmoji for visual clarity:

```bash
git add .
git commit -m "✨ feat: add X support"

```

### 5. Sync with Upstream

Keep your branch up-to-date with the main `canary` branch:

```bash
git remote add upstream https://github.com/lobehub/lobe-chat.git
git fetch upstream
git merge upstream/canary

```

### 6. Submit a Pull Request

Push your branch and open a PR:

```bash
git push origin feature/your-feature-name

```

Navigate to the repository on GitHub and click **Compare & pull request**. Fill out the PR template located at [`.github/PULL_REQUEST_TEMPLATE.md`](https://github.com/lobehub/lobe-chat/blob/main/.github/PULL_REQUEST_TEMPLATE.md) and submit for review.

## Practical Example: Adding a Zustand Slice

Suppose you want to introduce a **bookmark** feature that stores user-saved messages. This example demonstrates the architectural pattern used throughout the Lobe Chat project.

### Step 1: Create the Slice File

Create [`src/store/bookmark/slices/items.ts`](https://github.com/lobehub/lobe-chat/blob/main/src/store/bookmark/slices/items.ts):

```typescript
// src/store/bookmark/slices/items.ts
import { createSlice } from 'zustand';
import type { BookmarkItem } from '@/types';

export const initialState: BookmarkItem[] = [];

export const bookmarkSlice = createSlice((set, get) => ({
  items: initialState,
  add: (item: BookmarkItem) =>
    set(state => ({ items: [...state.items, item] })),
  remove: (id: string) =>
    set(state => ({ items: state.items.filter(i => i.id !== id) })),
}));

```

### Step 2: Expose the Slice in the Store Index

Update [`src/store/bookmark/index.ts`](https://github.com/lobehub/lobe-chat/blob/main/src/store/bookmark/index.ts):

```typescript
// src/store/bookmark/index.ts
import { create } from 'zustand';
import { bookmarkSlice } from './slices/items';

export const useBookmarkStore = create(bookmarkSlice);

```

### Step 3: Consume in a Component

Create [`src/features/bookmark/BookmarkList.tsx`](https://github.com/lobehub/lobe-chat/blob/main/src/features/bookmark/BookmarkList.tsx):

```tsx
import { useBookmarkStore } from '@/store/bookmark';

export const BookmarkList = () => {
  const items = useBookmarkStore(state => state.items);
  const remove = useBookmarkStore(state => state.remove);

  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {item.title}
          <button onClick={() => remove(item.id)}>✕</button>
        </li>
      ))}
    </ul>
  );
};

```

### Step 4: Add Unit Tests

Create [`src/store/bookmark/slices/items.test.ts`](https://github.com/lobehub/lobe-chat/blob/main/src/store/bookmark/slices/items.test.ts):

```typescript
import { bookmarkSlice, initialState } from './items';

test('adds a bookmark', () => {
  const set = jest.fn();
  const get = jest.fn();
  const api = bookmarkSlice(set, get);
  api.add({ id: '1', title: 'Demo' });

  expect(set).toHaveBeenCalledWith({
    items: [{ id: '1', title: 'Demo' }],
  });
});

```

### Step 5: Validate Your Changes

Run the quality checks before committing:

```bash
pnpm lint && bunx vitest run

```

This pattern mirrors existing slice implementations such as `src/store/video/slices/*`, ensuring architectural consistency across the Lobe Chat project.

## Key Files Every Contributor Should Know

Understanding these critical paths will help you navigate the Lobe Chat codebase effectively:

| Path | Purpose | GitHub Link |
|------|---------|-------------|
| [`README.md`](https://github.com/lobehub/lobe-chat/blob/main/README.md) | High-level project description, features, deployment guides | [README.md](https://github.com/lobehub/lobe-chat/blob/canary/README.md) |
| [`CONTRIBUTING.md`](https://github.com/lobehub/lobe-chat/blob/main/CONTRIBUTING.md) | Detailed contribution workflow, coding style, PR process | [CONTRIBUTING.md](https://github.com/lobehub/lobe-chat/blob/canary/CONTRIBUTING.md) |
| [`pnpm-workspace.yaml`](https://github.com/lobehub/lobe-chat/blob/main/pnpm-workspace.yaml) | Workspace configuration for the monorepo | [pnpm-workspace.yaml](https://github.com/lobehub/lobe-chat/blob/canary/pnpm-workspace.yaml) |
| `src/app/**` | Next.js app router entry points (global layout, CSS, providers) | [src/app](https://github.com/lobehub/lobe-chat/tree/canary/src/app) |
| `src/routes/**` | Page-level route components (e.g., share, chat, settings) | [src/routes](https://github.com/lobehub/lobe-chat/tree/canary/src/routes) |
| `src/store/**` | Zustand stores – the single source of truth for UI state | [src/store](https://github.com/lobehub/lobe-chat/tree/canary/src/store) |
| `src/utils/server/**` | Server-side helpers for model parsing and routing | [src/utils/server](https://github.com/lobehub/lobe-chat/tree/canary/src/utils/server) |
| `src/styles/**` | Global styling and Ant Design overrides | [src/styles](https://github.com/lobehub/lobe-chat/tree/canary/src/styles) |
| `src/store/electron/**` | Electron desktop integration (IPC, hotkeys) | [src/store/electron](https://github.com/lobehub/lobe-chat/tree/canary/src/store/electron) |
| `tests/**` | Vitest unit-test suites | [tests](https://github.com/lobehub/lobe-chat/tree/canary/tests) |

## Summary

Contributing to the Lobe Chat project requires understanding its monorepo architecture and established workflows:

- **Architecture**: The project uses Next.js 16 with React 19, TypeScript, and Zustand for state management in a pnpm workspace monorepo structure.

- **Setup**: Fork the repository, clone locally, and run `pnpm install` to initialize the workspace dependencies.

- **Development**: Create feature branches from `canary`, follow the slice pattern in `src/store/*/slices/*` for state management, and adhere to ESLint/Prettier rules via `pnpm lint`.

- **Testing**: Write unit tests in `src/**/*.test.*` files and validate with `bunx vitest run` before submitting.

- **Submission**: Sync with upstream `canary` branch, push to your fork, and open a PR using the template in [`.github/PULL_REQUEST_TEMPLATE.md`](https://github.com/lobehub/lobe-chat/blob/main/.github/PULL_REQUEST_TEMPLATE.md).

## Frequently Asked Questions

### What branch should I target when contributing to Lobe Chat?

Always target the `canary` branch when opening pull requests. The `canary` branch serves as the main integration branch where features are tested before reaching stable releases. Sync your fork regularly with `git fetch upstream` and `git merge upstream/canary` to avoid merge conflicts.

### How do I add new state management features to the codebase?

Follow the **Zustand slice pattern** established in the project. Create your logic in `src/store/<feature>/slices/*.ts`, then combine it in `src/store/<feature>/index.ts` using `create()`. This modular approach keeps the global store composable and matches existing implementations like `src/store/video/slices/*`.

### What testing framework does Lobe Chat use?

The project uses **Vitest** for unit testing. Write tests in files matching `src/**/*.test.*` or in the `tests/` directory. Run the full suite with `bunx vitest run` before committing. New logic should include corresponding unit tests to maintain code quality and prevent regressions.

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

The comprehensive contribution guide lives in [`CONTRIBUTING.md`](https://github.com/lobehub/lobe-chat/blob/main/CONTRIBUTING.md) at the repository root. This document contains detailed information about coding standards, commit message conventions (gitmoji is encouraged), the PR template location at [`.github/PULL_REQUEST_TEMPLATE.md`](https://github.com/lobehub/lobe-chat/blob/main/.github/PULL_REQUEST_TEMPLATE.md), and specific instructions for setting up the development environment.