Skip to main content

Self-hosting installation

Toots is open source and can be self-hosted on your own infrastructure. This guide covers both Docker-based deployment and local development setup.

Prerequisites

Before you begin, ensure you have:
  • Node.js ≥ 20
  • pnpm (package manager)
  • PostgreSQL 16 or later (local or Docker)
  • Google Gemini API key (for AI ticket generation)
Toots uses a monorepo structure with pnpm workspaces and Turborepo for efficient builds and development.

Quick start with Docker

The fastest way to run Toots is using Docker Compose for the database.
1

Clone the repository

git clone https://github.com/topboyasante/toots.git
cd toots
2

Install dependencies

pnpm install
This installs dependencies for all packages in the monorepo, including:
  • apps/web — The Next.js application
  • packages/ui — Shared shadcn/ui components
  • packages/typescript-config — Shared TypeScript configs
3

Start PostgreSQL with Docker

docker compose up -d
This starts a PostgreSQL 16 container based on the included compose.yaml:
services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}
    ports:
      - "5432:5432"
    volumes:
      - db_data:/var/lib/postgresql/data
Set POSTGRES_USER, POSTGRES_PASSWORD, and POSTGRES_DB in a root .env file or export them. Defaults are often: postgres / postgres / toots.
4

Configure environment variables

Create a .env file in apps/web with the following variables:
# Database connection
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/toots"

# Authentication (better-auth)
BETTER_AUTH_SECRET="your-random-secret-key-here"
BETTER_AUTH_URL="http://localhost:3000"

# AI provider (Google Gemini)
GOOGLE_GENERATIVE_AI_API_KEY="your-gemini-api-key-here"
Replace your-random-secret-key-here with a strong random string for session signing. You can generate one with: openssl rand -base64 32
Get a free Gemini API key from Google AI Studio
5

Run database migrations

pnpm --filter web db:migrate
This applies Prisma migrations to create the database schema:
// Key models in schema.prisma:
model User {
  id            String    @id @default(cuid())
  email         String    @unique
  name          String?
  projects      Project[]
  // ... auth fields
}

model Project {
  id          String    @id @default(cuid())
  name        String
  description String?
  userId      String
  tickets     Ticket[]
  messages    Message[]
}

model Ticket {
  id                 String   @id @default(cuid())
  projectId          String
  title              String
  type               String   // Story, Task, Epic, Bug, Technical Debt
  priority           String   // High, Medium, Low
  description        String
  acceptanceCriteria Json
  estimatedEffort    String
  dependencies       Json
  labels             Json
  status             String   @default("todo")
}
6

Start the development server

pnpm dev
This starts the Next.js application with Turbopack for fast refresh. Open http://localhost:3000 in your browser.

Local development setup

For active development, you may prefer running PostgreSQL locally without Docker.
1

Install PostgreSQL locally

Install PostgreSQL 16+ for your platform:macOS (Homebrew):
brew install postgresql@16
brew services start postgresql@16
Ubuntu/Debian:
sudo apt update
sudo apt install postgresql-16
sudo systemctl start postgresql
2

Create the database

createdb toots
Or via psql:
CREATE DATABASE toots;
3

Update DATABASE_URL

In apps/web/.env, set:
DATABASE_URL="postgresql://your-user@localhost:5432/toots"
Replace your-user with your PostgreSQL username (often your system username).
4

Follow steps 2-6 from Docker setup

Continue with installing dependencies, configuring environment variables, running migrations, and starting the dev server.

Useful development commands

Toots uses Turborepo and pnpm workspaces for efficient task execution.
# Start Next.js dev server with Turbopack
pnpm dev

Adding UI components

Toots uses shadcn/ui components stored in a shared packages/ui package.
1

Add a new component

From the repository root:
pnpm dlx shadcn@latest add button -c apps/web
This installs the component into packages/ui/src/components.
2

Use the component

Import from the shared UI package:
import { Button } from "@workspace/ui/components/button"

export default function MyComponent() {
  return <Button>Click me</Button>
}
Tailwind CSS and globals.css are configured to use the shared ui package, so all styling works automatically.

Architecture overview

Toots is built as a monorepo with the following structure:
toots/
├── apps/
│   └── web/                 # Next.js application
│       ├── app/             # App Router pages and layouts
│       ├── lib/             # Utilities, auth, oRPC, DB
│       ├── prisma/          # Database schema and migrations
│       └── package.json
├── packages/
│   ├── ui/                  # Shared shadcn/ui components
│   ├── typescript-config/   # Shared TypeScript configs
│   └── eslint-config/       # Shared ESLint configs
├── compose.yaml             # Docker Compose for PostgreSQL
├── turbo.json               # Turborepo configuration
└── pnpm-workspace.yaml      # pnpm workspace definition

Key technologies

  • Next.js 16 — App Router with React 19 and Server Components
  • oRPC — Type-safe RPC layer replacing REST/GraphQL
  • Prisma ORM — Type-safe database client with migrations
  • better-auth — Modern authentication with email/password
  • Vercel AI SDK — Streaming AI responses from Google Gemini
  • dnd-kit — Accessible drag-and-drop for Kanban board

Production deployment

For production, you can deploy Toots to any platform that supports Next.js.
1

Connect your repository

Import the Toots repository in Vercel
2

Configure environment variables

Add all variables from apps/web/.env in the Vercel project settings:
  • DATABASE_URL
  • BETTER_AUTH_SECRET
  • BETTER_AUTH_URL (set to your production domain)
  • GOOGLE_GENERATIVE_AI_API_KEY
3

Deploy

Vercel will automatically build and deploy. The build command includes:
prisma generate && prisma migrate deploy && next build

Database migrations

Toots uses Prisma for database management. When the schema changes:
1

Edit the schema

Modify apps/web/prisma/schema.prisma to add or change models
2

Create a migration

pnpm --filter web db:migrate
This creates a migration file in prisma/migrations/ and applies it to the database.
3

Deploy to production

The build script automatically runs prisma migrate deploy to apply pending migrations:
pnpm build  # Includes: prisma migrate deploy
Always test migrations in a staging environment before deploying to production.

Troubleshooting

Check that:
  • PostgreSQL is running (docker ps or pg_isready)
  • DATABASE_URL is correctly formatted: postgresql://user:password@host:port/database
  • Firewall allows connections on port 5432
  • Database exists (createdb toots if needed)
Regenerate the Prisma client:
pnpm --filter web db:generate
If schema changes aren’t reflected, run migrations:
pnpm --filter web db:migrate
Verify your GOOGLE_GENERATIVE_AI_API_KEY is valid:
  • Get a key from Google AI Studio
  • Check API quota limits
  • Ensure the key is correctly set in .env
Clear the workspace and reinstall:
rm -rf node_modules packages/*/node_modules apps/*/node_modules
pnpm install
Ensure:
  • Environment variables are set in your hosting platform
  • prisma generate runs before build (it’s in the build script)
  • All dependencies are installed with pnpm install --frozen-lockfile

Next steps

Quickstart guide

Learn how to use Toots to create projects and generate tickets

Setup & Configuration

Configure environment variables, database, and integrations

Contributing

Pick up issues and contribute to the project

API reference

Explore the oRPC API endpoints and types

Build docs developers (and LLMs) love