- Node.js 18+
- pnpm 9+
# Install pnpm if not already installed
npm install -g pnpm# 1. Install dependencies
pnpm install
# 2. Build tokens (required before other packages)
pnpm --filter @blog/tokens build
# 3. Start development servers
pnpm dev# Clone and enter the project
cd sarajevo
# Install all workspace dependencies
pnpm install
# Build design tokens
pnpm --filter @blog/tokens build
# Verify token build succeeded
ls packages/tokens/build/
# Should show: css/ js/# Install any new dependencies
pnpm install
# Rebuild tokens if token files changed
pnpm --filter @blog/tokens build# Start all dev servers (once apps are created)
pnpm dev
# Start specific package
pnpm --filter @blog/blog dev # Blog app
pnpm --filter @blog/tokens build # Rebuild tokens# Build all packages
pnpm build
# Build specific package
pnpm --filter @blog/tokens build
pnpm --filter @blog/ui build
pnpm --filter @blog/blog build# Clean all build artifacts
pnpm clean
# Clean and reinstall
pnpm clean && pnpm install# Lint all packages
pnpm lint
# Format all files
pnpm format@blog/blog (apps/blog)
├── @blog/ui
│ └── @blog/tokens
└── @blog/config
@blog/ui (packages/ui)
├── @blog/tokens
└── @blog/config
@blog/tokens (packages/tokens)
└── (no internal dependencies)
@blog/config (packages/config)
└── (no internal dependencies)
Build Order: tokens → ui → blog
# Add to root (dev tools)
pnpm add -D -w <package>
# Add to specific package
pnpm --filter @blog/ui add <package>
pnpm --filter @blog/blog add <package>
# Add workspace dependency
pnpm --filter @blog/ui add @blog/tokens@workspace:*-
Create component file:
packages/ui/src/components/NewComponent.tsx -
Export from index:
// packages/ui/src/index.tsx export { NewComponent } from '@ui/components/NewComponent';
-
Add story (once Storybook is set up):
apps/docs/stories/NewComponent.stories.tsx
-
Create component file:
apps/blog/components/NewComponent.tsx -
Import UI primitives:
import { Card, Badge } from '@blog/ui';
-
Edit token JSON in
packages/tokens/src/:// packages/tokens/src/colors.json { "color": { "brand": { "primary": { "value": "#your-color" } } } }
-
Rebuild tokens:
pnpm --filter @blog/tokens build
-
Use in CSS or components:
color: var(--color-brand-primary);
# Rebuild tokens
pnpm --filter @blog/tokens build
# Clear turbo cache
rm -rf .turbo
# Reinstall dependencies
pnpm installEnsure your tsconfig.json extends the correct base:
{
"extends": "@blog/config/tsconfig/react.json",
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@ui/*": ["src/*"]
}
}
}-
Check Tailwind content paths include the UI package:
// tailwind.config.js content: [ './src/**/*.{ts,tsx}', '../../packages/ui/src/**/*.{ts,tsx}' ]
-
Verify globals.css imports tokens before Tailwind:
@import '@blog/tokens/css'; @tailwind base; @tailwind components; @tailwind utilities;
# Clear pnpm cache
pnpm store prune
# Remove lockfile and reinstall
rm pnpm-lock.yaml
pnpm installRecommended extensions:
- ESLint
- Prettier
- Tailwind CSS IntelliSense
- TypeScript + JavaScript
Workspace settings (.vscode/settings.json):
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"typescript.preferences.importModuleSpecifier": "non-relative"
}Create .env.local in apps/blog/ for local development:
# Example (none required yet)
# NEXT_PUBLIC_SITE_URL=http://localhost:3000The blog deploys to GitHub Pages via static export:
# Build for production
pnpm build
# Static files are output to docs/The docs/ directory is served by GitHub Pages at ftvision.github.io.