Development Workflow

This guide covers everything you need to know for daily development with TurboStack.

Development Commands

Starting Applications

# Start all applications (parallel with Turborepo)
bun run dev
Starts frontend (4100), backend (4101), and docs (4102)

Port Information

ApplicationPortURL
🖥️ Frontend4100localhost:4100
Backend4101localhost:4101
📚 API Docs4101localhost:4101/openapi
📖 Docs Site4102localhost:4102

Database Commands

Generate Client

bash bun run db:generate Regenerate Prisma client after schema changes

Push Schema

bash bun run db:push Apply schema to database (dev only)

Create Migration

bash bun run db:migrate Create and apply migration files

Prisma Studio

bash bun run db:studio Visual database browser at localhost:5555

Development Workflow

1. Adding a New API Route

1

Create Route File

Create a new route file in apps/backend/src/routes/:
// apps/backend/src/routes/products.ts
import { Elysia, t } from "elysia";
import { db } from "@repo/database";

export const productRoutes = new Elysia({ prefix: "/products" })
  .get("/", async () => {
    const products = await db.product.findMany();
    return { success: true, data: products };
  })
  .post(
    "/",
    async ({ body }) => {
      const product = await db.product.create({
        data: body,
      });
      return { success: true, data: product };
    },
    {
      body: t.Object({
        name: t.String(),
        price: t.Number(),
      }),
    }
  );
2

Register Route

Add to apps/backend/src/index.ts:
import { productRoutes } from "./routes/products";

app.use(productRoutes);
3

Test with Swagger

Visit localhost:4101/openapi to test your new endpoints.

2. Adding a UI Component

1

Create Component

Add component to packages/ui/src/:
// packages/ui/src/input.tsx
import * as React from "react";

export interface InputProps
  extends React.InputHTMLAttributes<HTMLInputElement> {}

export const Input = React.forwardRef<HTMLInputElement, InputProps>(
  ({ className, ...props }, ref) => {
    return <input ref={ref} className={className} {...props} />;
  }
);
Input.displayName = "Input";
2

Export Component

Add to packages/ui/src/index.ts:
export { Input, type InputProps } from "./input";
3

Use in Frontend

// apps/frontend/app/page.tsx
import { Input } from "@repo/shadcn-ui";

export default function Page() {
  return <Input placeholder="Enter text..." />;
}

3. Database Schema Update

1

Update Schema

Edit packages/database/prisma/schema.prisma:
model Post {
  id        String   @id @default(cuid())
  title     String
  content   String?
  authorId  String
  author    User     @relation(fields: [authorId], references: [id])
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  @@map("posts")
}

model User {
  id    String @id @default(cuid())
  // ... existing fields
  posts Post[]
}
2

Create Migration

bash bun run db:migrate Enter a descriptive migration name when prompted.
3

Generate Client

bun run db:generate
Regenerate Prisma client with new types.

Turborepo Filtering

Run commands for specific packages:
# Build only UI package
bun run build --filter=@repo/shadcn-ui

# Build frontend and its dependencies

bun run build --filter=frontend...

# Build package and its dependents

bun run build --filter=...@repo/database


Code Quality

Linting

# Run ESLint
bun run lint

# Auto-fix issues
bun run lint:fix

Type Check

# TypeScript check
bun run check-types

Format

# Format with Prettier
bun run format

Build

# Build all apps
bun run build

Debugging

Backend Debugging

Use console.log() or console.error():
console.log("User data:", user);
console.error("Error:", error);

Frontend Debugging

Install React DevTools browser extension.

Docker Development

# Start all containers
docker-compose up -d

# View logs
docker-compose logs -f

# Stop containers
docker-compose down

Environment Variables

Development Setup

Create .env in project root:
# Database
DATABASE_URL="postgresql://user:password@localhost:5432/turbostack"

# Security
JWT_SECRET="your-super-secret-jwt-key-min-32-characters"
SESSION_SECRET="another-super-secret-session-key"

# URLs
FRONTEND_URL="http://localhost:4100"
NEXT_PUBLIC_API_URL="http://localhost:4101"

# Optional Services
RESEND_API_KEY="re_..."
POLAR_ACCESS_TOKEN="polar_at_..."
Never commit .env files to version control. Always use .env.example as a template.

Troubleshooting

# Find process using port
lsof -i :4100

# Kill the process
kill -9 <PID>
# Regenerate Prisma Client
bun run db:generate

# Clear node_modules and reinstall
rm -rf node_modules bun.lockb
bun install
  1. Regenerate Prisma Client: bun run db:generate 2. Restart TypeScript server in VS Code 3. Clear Next.js cache: rm -rf apps/frontend/.next
# Clear Turborepo cache
bun run turbo clean

# Force rebuild
bun run build --force

Best Practices

Git Workflow

  • Create feature branches - Write meaningful commit messages - Keep commits atomic - Review changes before committing

Code Style

  • Follow ESLint rules - Use Prettier for formatting - Write JSDoc comments - Keep functions small

Testing

  • Write tests for business logic - Test API endpoints - Use MSW for API mocking - Maintain high coverage

Performance

  • Use Server Components - Minimize client bundles - Optimize images - Monitor bundle size

Next Steps