---
title: "Create Snippet Manager App"
description: "Create the apps/snippet-manager directory, configure it to run on port 3001, add dependency on packages/ui, and create a basic home page."
canonical_url: "https://vercel.com/academy/production-monorepos/create-snippet-app"
md_url: "https://vercel.com/academy/production-monorepos/create-snippet-app.md"
docset_id: "vercel-academy"
doc_version: "1.0"
last_updated: "2026-04-11T15:56:34.924Z"
content_type: "lesson"
course: "production-monorepos"
course_title: "Production Monorepos with Turborepo"
prerequisites:  []
---

<agent-instructions>
Vercel Academy — structured learning, not reference docs.
Lessons are sequenced.
Adapt commands to the human's actual environment (OS, package manager, shell, editor) — detect from project context or ask, don't assume.
The lesson shows one path; if the human's project diverges, adapt concepts to their setup.
Preserve the learning goal over literal steps.
Quizzes are pedagogical — engage, don't spoil.
Quiz answers are included for your reference.
</agent-instructions>

# Create Snippet Manager App

# Create snippet manager app

You have a marketing site (apps/web) that uses shared UI components from `packages/ui`. Pretty cool but could be even better with another app. You'll build a snippet manager app that imports `Button` and `Card` from the same `packages/ui` - proving that your shared package works across multiple applications.

## Outcome

Create a second Next.js app (apps/snippet-manager) running on port 3001 that's configured to use the shared packages/ui library.

## Fast track

1. Use `create-next-app` to scaffold the app
2. Rename package and change port to 3001
3. Add workspace dependency on packages/ui

## Hands-on exercise 3.1

Create the snippet manager application using Next.js CLI.

**Requirements:**

1. Use `create-next-app` to scaffold apps/snippet-manager
2. Rename package to `@geniusgarage/snippet-manager` and set dev port to 3001
3. Add `@geniusgarage/ui` workspace dependency
4. Create simple home page placeholder

**Implementation hints:**

- Use `--typescript --app --no-tailwind` flags (we'll style with inline CSS like the web app)
- Port 3001 avoids conflict with web app on 3000
- `workspace:*` links to local packages/ui
- Verify both apps can run simultaneously

## Create app with Next.js CLI

Run create-next-app inside the apps directory:

```bash
cd apps
npx create-next-app@latest snippet-manager --typescript --app --no-tailwind --no-src-dir --import-alias "@/*" --eslint --no-react-compiler
```

This creates:

```
  apps/snippet-manager/
  ├── app/
  │   ├── layout.tsx
  │   ├── page.tsx
  │   └── globals.css
  ├── package.json
  ├── next.config.ts
  ├── tsconfig.json
  └── ...
```

**Flags explained:**

- `--typescript` - Use TypeScript
- `--app` - Use App Router
- `--no-tailwind` - Skip Tailwind
- `--no-src-dir` - No src/ directory
- `--import-alias "@/*"` - Set up path alias
- `--eslint` - Add ESLint configuration
- `--no-react-compiler` - Skip React compiler for now

## Rename package and change port

Update the generated `apps/snippet-manager/package.json`:

```json title="apps/snippet-manager/package.json" {2,5}
{
  "name": "@geniusgarage/snippet-manager",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev --port 3001",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  }
  ...
}
```

**Changes:**

- `"name"` → `"@geniusgarage/snippet-manager"` - Match workspace naming
- `"dev"` → Add `--port 3001` - Run alongside web app

## Add UI package dependency

Add the shared UI package:

```bash
pnpm add @geniusgarage/ui --filter @geniusgarage/snippet-manager --workspace
```

This adds to your dependencies:

```json title="apps/snippet-manager/package.json" {3}
{
  "dependencies": {
    "@geniusgarage/ui": "workspace:*",
    "next": "^16.0.0",
    "react": "^19.0.0",
    "react-dom": "^19.0.0"
  }
}
```

The `workspace:*` protocol tells pnpm this is a local workspace package.

## Create home page

Replace the generated `apps/snippet-manager/app/page.tsx` with a simple placeholder:

```tsx title="apps/snippet-manager/app/page.tsx"
export default function Home() {
  return (
    <div style={{ padding: '2rem', fontFamily: 'system-ui', maxWidth: '800px', margin: '0 auto' }}>
      <h1 style={{ fontSize: '2.5rem', marginBottom: '1rem' }}>GeniusGarage Snippet Manager</h1>
      <p style={{ fontSize: '1.25rem', color: '#666' }}>
        Your code snippets, organized and ready to use.
      </p>
    </div>
  )
}
```

We'll build out the full snippet interface in the next lesson. For now, this confirms the app works.

## Try it

### 1. Verify workspace configuration

Check that pnpm recognizes both apps:

```bash
pnpm ls --depth 0
```

All three packages are linked in the workspace.

You can run a similar command with turbo. Try:

```bash
npx turbo ls
```

### 2. Start the snippet manager app

```bash
pnpm --filter @geniusgarage/snippet-manager dev
```

Output:

```
> @geniusgarage/snippet-manager@1.0.0 dev
> next dev --port 3001

  ▲ Next.js 16.0.0
  - Local:        http://localhost:3001

✓ Starting...
✓ Ready in 1.8s
```

Open <http://localhost:3001> - you should see "GeniusGarage Snippet Manager".

### 3. Run both apps simultaneously

Stop the previous command and run both apps with Turborepo:

```bash
pnpm dev
```

Because turbo.json configures dev tasks, both apps start:

```
@geniusgarage/web:dev: ready started server on 0.0.0.0:3000
@geniusgarage/snippet-manager:dev: ready started server on 0.0.0.0:3001
```

Visit both:

- <http://localhost:3000> - Marketing site with features page
- <http://localhost:3001> - Snippet manager (placeholder)

Both apps running from one command - that's monorepo orchestration. And you are the conductor!

### 4. Build both apps with Turborepo

Stop dev servers and build:

```bash
turbo build
```

Output:

```
@geniusgarage/web:build: cache miss, executing 5.123s
@geniusgarage/snippet-manager:build: cache miss, executing 4.891s

Tasks:    2 successful, 2 total
Cached:   0 cached, 2 total
Time:     5.234s
```

Notice:

- **Both apps build in parallel** (no dependency between them)
- **No UI build** - the UI package is just source files (you'll add a build task in Section 3)
- **Both cache miss** because this is the first build of snippet-manager

This is Turborepo's task orchestration in action.

## How it works

Your monorepo now has:

```
  production-monorepos-starter/
  ├── apps/
  │   ├── web/              (port 3000)
  │   └── app/              (port 3001) ← New!
  ├── packages/
  │   └── ui/               (shared components)
  ├── package.json
  └── pnpm-workspace.yaml
```

**Workspace dependencies:**

- apps/web depends on packages/ui
- apps/snippet-manager depends on packages/ui (new!)

**Turborepo orchestration:**

1. Run `turbo build`
2. Build packages/ui first (both apps depend on it)
3. Build apps/web and apps/snippet-manager in parallel
4. Cache all three builds

**Development workflow:**

- `pnpm dev` runs both apps simultaneously
- Edit packages/ui - hot reload updates both apps instantly
- Build once, use everywhere

## Commit

```bash
git add .
git commit -m "feat(app): add snippet manager app on port 3001"
```

## Done-when

Verify your second app is configured:

- [ ] Used `create-next-app` to scaffold `apps/snippet-manager`
- [ ] Renamed package to `@geniusgarage/snippet-manager` in package.json
- [ ] Set dev script to run on port 3001
- [ ] Added `@geniusgarage/ui` as workspace dependency
- [ ] Created simple home page with inline styles
- [ ] Ran `pnpm install` to link workspace packages
- [ ] Verified app runs on <http://localhost:3001>
- [ ] Ran both apps simultaneously with `pnpm dev`
- [ ] Built both apps with `turbo build` and saw parallel execution

## What's next

Your snippet manager app is running, but it doesn't use any shared components yet. Next lesson: **Build Snippet List Page** - you'll import `Button` and `Card` from `packages/ui` and display mock snippet data, proving code sharing works across apps.


---

[Full course index](/academy/llms.txt) · [Sitemap](/academy/sitemap.md)
