First off, thank you for considering contributing to Tabby! It's people like you that make Tabby such a great tool.
Before you dive in, check out our Documentation for detailed guides on architecture, features, and APIs. It's the best place to understand how Tabby works under the hood.
This document covers the contribution workflow, coding guidelines, and local development setup.
If you find a bug in the source code, you can help us by submitting an issue to our GitHub repository. Please include:
- A clear, descriptive title
- Steps to reproduce the behavior
- Expected vs. actual behavior
- Screenshots or logs, if applicable
- Your OS version and Node.js version
Even better, you can submit a Pull Request with a fix!
If you have an idea for a feature or an enhancement, please open an issue explaining your idea. Describe the use case and why it would be valuable to other users.
Not sure where to start? Look for issues tagged with good first issue - these are scoped for newcomers to the codebase.
-
Fork the repository on GitHub.
-
Clone your fork locally:
git clone https://github.com/<your-username>/tabby.git cd tabby
-
Add the upstream remote so you can keep your fork in sync:
git remote add upstream https://github.com/TabbyAIKeyboard/tabby.git
-
Create a feature branch from
main:git checkout -b feature/your-feature-name
Use a descriptive branch name. Prefix it based on the type of change:
Prefix Use for feature/New features fix/Bug fixes docs/Documentation changes refactor/Code refactoring -
Keep your branch up to date with upstream:
git fetch upstream git rebase upstream/main
We use Conventional Commits. Each commit message should follow this format:
<type>(<scope>): <short description>
[optional body]
[optional footer]
Types:
| Type | Description |
|---|---|
feat |
A new feature |
fix |
A bug fix |
docs |
Documentation only changes |
style |
Formatting, missing semicolons, etc. (no code change) |
refactor |
Code change that neither fixes a bug nor adds a feature |
test |
Adding or updating tests |
chore |
Build process, CI, or tooling changes |
Examples:
feat(copilot): add multi-language support for code analysis
fix(voice-agent): resolve audio cutoff on long responses
docs(readme): update installation instructions
When your changes are ready:
- Test your changes locally - make sure the app builds and runs correctly.
- Push your branch to your fork:
git push origin feature/your-feature-name
- Open a Pull Request against the
mainbranch ofTabbyAIKeyboard/tabby. - In the PR description:
- Summarize what you changed and why
- Reference any related issues (e.g.,
Closes #42) - Include screenshots for UI changes
- A maintainer will review your PR. Be prepared to make revisions based on feedback.
Note: The project uses Husky and lint-staged for pre-commit hooks. Formatting and type checks run automatically on staged files when you commit.
| Requirement | Version | Notes |
|---|---|---|
| Node.js | 18+ | |
| Python | 3.12+ | For memory backend |
| uv | Latest | Python package manager |
| pnpm | Latest | JavaScript package manager |
| Docker Desktop | Latest | For local Supabase |
| OpenAI API key | — | Required |
Optional API keys
git clone https://github.com/<your-username>/tabby.git
cd tabby
pnpm install # Root dependencies (Husky, lint-staged)
# Frontend
cd frontend && pnpm install
# Next.js Backend
cd ../nextjs-backend && pnpm install
# Memory Backend
cd ../backend && uv syncWe use a local Supabase instance running in Docker.
- Start Docker Desktop and wait for it to fully initialize.
- Initialize Supabase in the project root (first time only):
npx supabase init
- Start local Supabase:
The first run will pull ~13 Docker images (takes a few minutes). Subsequent starts take ~10 seconds.
npx supabase start
- When completed, it prints all credentials. Note the API URL, anon key, and service_role key.
- The database schema is auto-applied from
supabase/migrations/.
Supabase Quick Reference
| Action | Command |
|---|---|
| Start | npx supabase start |
| Stop | npx supabase stop |
| Status | npx supabase status |
| Admin UI | http://localhost:54323 |
| Reset DB | npx supabase db reset |
Note: Docker Desktop must be running before
npx supabase start.
Neo4j (Knowledge Graph -- Optional)
- Create a free instance at Neo4j AuraDB.
- Save the Text File containing your credentials (URI, username, password) when creating the instance.
- Note your Instance ID and Instance Name from the dashboard.
Copy the example env files, then fill in the Supabase credentials from npx supabase status:
cp frontend/env.example frontend/.env.local
cp nextjs-backend/env.example nextjs-backend/.env.local
cp backend/env.example backend/.envFrontend -- frontend/.env.local
# Supabase (local Docker) -- get values from `npx supabase status`
NEXT_PUBLIC_SUPABASE_URL="http://127.0.0.1:54321"
NEXT_PUBLIC_SUPABASE_ANON_KEY="<ANON_KEY from supabase status>"
SUPABASE_ADMIN="<SERVICE_ROLE_KEY from supabase status>"
NEXT_PUBLIC_APP_NAME="Tabby"
NEXT_PUBLIC_APP_ICON="/logos/tabby-logo.png"
NEXT_PUBLIC_API_URL="http://localhost:3001"
NEXT_PUBLIC_MEMORY_API_URL="http://localhost:8000"Next.js Backend -- nextjs-backend/.env.local
# Supabase (local Docker) -- same keys as frontend
NEXT_PUBLIC_SUPABASE_URL="http://127.0.0.1:54321"
NEXT_PUBLIC_SUPABASE_ANON_KEY="<ANON_KEY from supabase status>"
SUPABASE_ADMIN="<SERVICE_ROLE_KEY from supabase status>"
RESEND_API_KEY=""
RESEND_DOMAIN=""
NEXT_PUBLIC_APP_NAME=Tabby
NEXT_PUBLIC_APP_ICON='/logos/tabby-logo.png'
# AI Providers
OPENAI_API_KEY=""
GOOGLE_GENERATIVE_AI_API_KEY=""
GROQ_API_KEY=""
CEREBRAS_API_KEY=""
OPENROUTER_API_KEY=""
TAVILY_API_KEY=""
MEMORY_API_URL="http://localhost:8000"Backend -- backend/.env
OPENAI_API_KEY=
# Local Supabase PostgreSQL -- get DB_URL from `npx supabase status`
SUPABASE_CONNECTION_STRING="postgresql://postgres:postgres@127.0.0.1:54322/postgres"
# Neo4j (optional)
NEO4J_URL=
NEO4J_USERNAME=
NEO4J_PASSWORD=# Terminal 0: Start local Supabase (Docker Desktop must be running)
npx supabase start
# Terminal 1: Start memory backend
cd backend && uv run main.py
# Terminal 2: Start Next.js backend
cd nextjs-backend && pnpm dev
# Terminal 3: Start Windows MCP server (optional)
cd frontend && pnpm run windows-mcp
# Terminal 4: Start Electron app
cd frontend && pnpm devOnce running:
| Service | URL |
|---|---|
| Supabase API | http://127.0.0.1:54321 |
| Supabase Studio | http://localhost:54323 |
| Frontend (Electron) | http://localhost:3000 |
| Next.js Backend | http://localhost:3001 |
| Memory API | http://localhost:8000 |
| Windows MCP | http://localhost:8001 |
The app runs in the system tray. Right-click for:
- Show Actions Menu
- Brain Panel
- Settings
- Quit
Thank you for helping make Tabby better!