Getting Started
Welcome to turbo-kit! This guide will walk you through creating your first project, setting it up, and getting familiar with the key files and structure. By the end of this tutorial, you'll have a running development server and understand the basics of the turbo-kit monorepo.
Creating Your Project
The easiest way to get started with turbo-kit is using the official CLI. Open your terminal and run:
pnpm create turbo-kit@latestThis command will:
- Prompt you for a project name
- Set up the entire monorepo structure
- Install all necessary dependencies
- Configure the project with sensible defaults
Follow the prompts, and once it's done, navigate into your new project directory:
cd your-project-nameInstalling Dependencies
With your project created, the next step is to install all dependencies. turbo-kit uses pnpm as its package manager, which provides fast, efficient dependency management for monorepos.
pnpm iThis will install all dependencies across all packages in the monorepo. The first install may take a few minutes, but subsequent installs will be much faster thanks to pnpm's efficient caching.
Configuring Environment Variables
Before you can run the development server, you'll need to set up your environment variables. The setup script already copies .env.example to .env for you, so you can skip that step.
Open the .env file and fill in the required values:
- Database URL: You'll need a PostgreSQL database URL. If you're using Supabase (recommended), you can get this from your Supabase project settings.
- Redis URL: For development, you can use Upstash (free tier available) or set up a local Redis instance.
- Auth secrets: Generate secure random strings for your authentication secrets.
Setting Up the Database
turbo-kit uses Drizzle ORM for type-safe database queries. Once you've configured your database URL, you need to push the schema to your database:
pnpm db:pushThis command will:
- Read your database schema from
packages/db/src/schema/index.ts - Generate the appropriate SQL migrations
- Push the schema to your database
If this is your first time running this command, it will create all the necessary tables. On subsequent runs, it will only apply changes.
Starting the Development Server
Now you're ready to start developing! turbo-kit uses Docker to run development services (like databases), and Next.js for the main application.
Start everything with:
pnpm run devThis single command will:
- Start Docker containers for development services (first run will download images)
- Start the Next.js development server
- Enable hot-reload for all your changes
The first time you run this, Docker will download the necessary images, which may take a few minutes. Subsequent runs will be much faster.
Once everything is running, open your browser and navigate to http://localhost:3000. You should see your turbo-kit application!
Exploring the Project Structure
Now that your project is running, let's explore some of the key files and understand how everything fits together.
Monorepo Structure
turbo-kit uses Turborepo to manage the monorepo. Here's what you'll find:
apps
├─ nextjs
│ ├─ Next.js 15
│ ├─ React 19
│ ├─ Tailwind CSS v4
│ └─ E2E Typesafe API Server & Client
packages
├─ api
│ └─ tRPC v11 router definition
├─ auth
│ └─ Authentication using better-auth.
├─ db
│ └─ Typesafe db calls using Drizzle & Supabase
├─ email
│ └─ React Email templates
├─ redis
│ └─ Upstash Redis client
├─ types
│ └─ The types used in the application
└─ ui
└─ Start of a UI package for the webapp using shadcn-ui
tooling
├─ eslint
│ └─ shared, fine-grained, eslint presets
├─ prettier
│ └─ shared prettier configuration
├─ tailwind
│ └─ shared tailwind theme and configuration
└─ typescript
└─ shared tsconfig you can extend from
Key Files to Know
Database Schema (packages/db/src/schema/index.ts)
This is where you define your database tables. Here's an example of how to define a table:
import { pgTable } from "drizzle-orm/pg-core";
export const posts = pgTable("posts", (t) => ({
id: t.uuid().notNull().primaryKey().defaultRandom(),
title: t.varchar({ length: 256 }).notNull(),
content: t.text().notNull(),
createdAt: t.timestamp().defaultNow().notNull(),
updatedAt: t
.timestamp({ mode: "date", withTimezone: true })
.$onUpdate(() => new Date()),
}));After defining tables here, run pnpm db:push to apply changes to your database.
tRPC Routers (packages/api/src/router/)
This is where you define your API endpoints. tRPC provides end-to-end type safety between your client and server. Routers are organized by feature, and you can create new routers as your app grows.
Example router structure:
import type { TRPCRouterRecord } from "@trpc/server";
import { z } from "zod/v4";
import { protectedProcedure, publicProcedure } from "../trpc";
export const postRouter = {
// Public query - anyone can call this
all: publicProcedure.query(async ({ ctx }) => {
return ctx.db.query.posts.findMany();
}),
// Protected mutation - requires authentication
create: protectedProcedure
.input(z.object({ title: z.string(), content: z.string() }))
.mutation(async ({ ctx, input }) => {
return ctx.db.insert(posts).values(input);
}),
} satisfies TRPCRouterRecord;Root Router (packages/api/src/root.ts)
All routers are combined here to create the main app router:
import { postRouter } from "./router/post";
import { createTRPCRouter } from "./trpc";
export const appRouter = createTRPCRouter({
post: postRouter,
// Add more routers here
});See the tRPC documentation for more in-depth information.
Next.js App (apps/nextjs/)
Your main Next.js application lives here. This is where you'll:
- Create pages and API routes
- Use tRPC clients to call your API
- Build your UI with React components
- Configure Next.js-specific settings
See the Next.js documentation for more information.
Authentication (packages/auth/)
turbo-kit uses Better Auth for authentication. The auth configuration is in packages/auth/src/index.ts. If you modify the auth setup (add providers, plugins, etc.), you'll need to regenerate the auth schema:
pnpm --filter @acme/auth generateThis generates the database schema for authentication tables in packages/db/src/schema/auth.ts.
React Email (packages/email/)
turbo-kit uses React Email for email templates. The email templates are in packages/email/src/templates/.
See the React Email documentation for more information.
Next Steps
Now that you have everything running, here are some recommended next steps:
-
Explore the Example Code: Check out the example routers and components to see how everything works together.
-
Add a Shadcn/ui Component: When you're ready to add a new component, use the interactive CLI:
pnpm ui-add -
Create a New Package: To add a new package to the monorepo:
pnpm turbo gen init -
Read the Documentation:
-
Set Up OAuth: For production deployments, consider deploying the auth proxy. See the deployment section for more details.
Troubleshooting
Port Already in Use
If port 3000 is already taken, Next.js will automatically use the next available port (3001, 3002, etc.). Your app will still work correctly.
Database Connection Issues
Make sure your POSTGRES_URL in .env is correct and that your database is accessible. If using Supabase, check that your project is active and the connection string is valid.
Docker Issues
If Docker containers fail to start, make sure Docker Desktop is running. Some common commands are:
# Start the containers
docker compose up -d
# Check the status of the containers
docker compose ps
# Stop the containers
docker compose down
# Check the logs of a container
docker compose logs <container>
# For example: docker compose logs postgres
Summary
Congratulations! You've successfully:
- ✅ Created a new turbo-kit project
- ✅ Installed all dependencies
- ✅ Configured environment variables
- ✅ Set up your database
- ✅ Started the development server
- ✅ Explored the project structure
You're now ready to start building your application. Happy hacking!