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
- Use
create-next-appto scaffold the app - Rename package and change port to 3001
- Add workspace dependency on packages/ui
Hands-on exercise 3.1
Create the snippet manager application using Next.js CLI.
Requirements:
- Use
create-next-appto scaffold apps/snippet-manager - Rename package to
@geniusgarage/snippet-managerand set dev port to 3001 - Add
@geniusgarage/uiworkspace dependency - Create simple home page placeholder
Implementation hints:
- Use
--typescript --app --no-tailwindflags (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:
cd apps
npx create-next-app@latest snippet-manager --typescript --app --no-tailwind --no-src-dir --import-alias "@/*" --eslint --no-react-compilerThis 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:
{
"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:
pnpm add @geniusgarage/ui --filter @geniusgarage/snippet-manager --workspaceThis adds to your dependencies:
{
"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:
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:
pnpm ls --depth 0All three packages are linked in the workspace.
You can run a similar command with turbo. Try:
npx turbo ls2. Start the snippet manager app
pnpm --filter @geniusgarage/snippet-manager devOutput:
> @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:
pnpm devBecause 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:
turbo buildOutput:
@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:
- Run
turbo build - Build packages/ui first (both apps depend on it)
- Build apps/web and apps/snippet-manager in parallel
- Cache all three builds
Development workflow:
pnpm devruns both apps simultaneously- Edit packages/ui - hot reload updates both apps instantly
- Build once, use everywhere
Commit
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-appto scaffoldapps/snippet-manager - Renamed package to
@geniusgarage/snippet-managerin package.json - Set dev script to run on port 3001
- Added
@geniusgarage/uias workspace dependency - Created simple home page with inline styles
- Ran
pnpm installto link workspace packages - Verified app runs on http://localhost:3001
- Ran both apps simultaneously with
pnpm dev - Built both apps with
turbo buildand 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.
Was this helpful?