Setting Up an AI-Built Portfolio on a New Machine
Setting Up an AI-Built Portfolio on a New Machine

I built this entire site through Claude Code — no traditional IDE, no manual coding. But what happens when I need to work from a different machine? Here's the full setup guide, including every gotcha I discovered.
What You Need
Before anything else, make sure you have:
- Node.js 20+ — the runtime
- Git — version control
- npm — package manager (comes with Node)
Everything else gets installed by the setup script.
The CLI Toolchain
This project depends on four CLI tools beyond Node:
| Tool | Purpose | Install |
|---|---|---|
gh | GitHub CLI for auth and repo management | brew install gh or cli.github.com |
vercel | Deployment CLI | npm install -g vercel |
turso | Database CLI for cloud SQLite | curl -sSfL https://get.tur.so/install.sh | bash |
claude | Claude Code for AI-assisted development | npm install -g @anthropic-ai/claude-code |
Each needs authentication:
gh auth login # GitHub vercel login # Vercel turso auth login # Turso # Claude Code authenticates on first run
Clone and Configure
git clone https://github.com/carlfung1003/ai-journey.git ~/ai-journey cd ~/ai-journey npm install npx prisma generate
The Git Email Gotcha
This one cost me hours. Vercel's GitHub integration rejects deploys if the git author email doesn't match the Vercel team. My work email gets blocked. The fix:
git config user.email "carlfung1003@users.noreply.github.com" git config user.name "carlfung1003"
Set this per-repo (not global) if you use different emails for different projects.
Database Credentials
The site uses Turso (cloud SQLite). You need three environment variables in .env:
TURSO_DATABASE_URL=libsql://your-db.turso.io
TURSO_AUTH_TOKEN=your-token-here
ADMIN_PASSWORD=your-admin-password
Get the credentials from Turso CLI:
turso db show ai-journey --url # Database URL turso db tokens create ai-journey # Auth token
The ADMIN_PASSWORD is whatever you choose — it protects the admin API endpoints for managing content.
Verify Everything Works
# Build the site npx next build # Start dev server npm run dev # Test the admin API curl -s http://localhost:3000/api/admin/posts \ -H "Authorization: Bearer your-password" | head -c 200
If the build succeeds and the API returns posts, you're good.
Claude Code Skills
The site was built with these Claude Code skills. Install them in a Claude Code session:
| Skill | What It Does |
|---|---|
senior-frontend | React/Next.js patterns, component architecture |
frontend-design | Visual design, animations, CSS |
vercel-react-best-practices | SSG optimization, performance |
senior-fullstack | Prisma, API routes, data architecture |
senior-backend | CRUD endpoints, auth patterns |
git-commit-helper | Commit message generation |
Find and install with /find-skills <name> inside Claude Code.
Deploy Pipeline
The deploy pipeline is simple:
- Make changes locally (via Claude Code or manually)
git push origin main- Vercel auto-deploys via GitHub integration
- Site is live in ~45 seconds
No CI/CD config needed — Vercel handles it.
Content Sanitization
This is critical. The site is public but content often originates from work context. Every piece of content must be sanitized before publishing.
What to Remove
- Company names and project codenames
- Team member names
- Internal IDs (Confluence pages, Google Sheets, Slack channels)
- Internal URLs
What to Replace With
Use generic terms: "my company", "a major finance platform", "the product", or role-based references like "the engineering lead" instead of names.
What's Safe to Keep
Claude Code, MCP, Atlassian MCP, Glean MCP, Confluence (as a generic tool), model names (Opus/Sonnet/Haiku), desk CLI.
Audit Before Every Push
grep -ri "your-company\|your-project\|internal-terms" src/lib/constants.ts
If it returns matches, fix them before pushing.
Admin API Quirks
A few things that aren't obvious:
- Dev server must be running (
npm run dev) to use the admin API - PUT expects
publishedas string"true", not boolean — the endpoint doesdata.published === "true" - PUT requires the
idfield (a cuid likecmm6o...), not the slug - POST creates with
published: falseby default — follow up with a PUT to publish
Four Gotchas That Will Save You Time
1. Vercel Build Cache Serves Stale CSS
You push a visual overhaul. Vercel says "Ready." But the site looks exactly the same. The build cache is serving old CSS bundles.
Fix: Push an empty commit to force a clean rebuild:
git commit --allow-empty -m "Force rebuild: clear Vercel cache" git push origin main
Verify by comparing the deployed CSS file size against your local .next/static/chunks/*.css.
2. Prisma orderBy Doesn't Work with Turso
Prisma's orderBy clause is silently ignored by the Turso (libSQL) adapter. Your blog posts will show in database insert order instead of date order.
Fix: Always sort in JavaScript after fetching:
function sortPostsByDate(posts: PostData[]): PostData[] { return posts.sort((a, b) => { const da = a.publishedAt ? new Date(a.publishedAt).getTime() : 0; const db = b.publishedAt ? new Date(b.publishedAt).getTime() : 0; return db - da; }); }
3. Keep Both Data Sources in Sync
The site uses a DB-first pattern with static fallback. When adding content, you must update both:
- The Turso database (via admin API POST)
- The
SAMPLE_*arrays insrc/lib/constants.ts
If you only update one, the site works but the fallback data is stale. If Turso goes down, visitors see outdated content.
4. Sanitize Everything
Run the audit grep before every content commit. It takes 2 seconds and prevents accidentally publishing internal references to a public site.
The Setup Script
All of the above is automated in setup.sh at the repo root. On a fresh machine:
git clone https://github.com/carlfung1003/ai-journey.git cd ai-journey bash setup.sh
It checks prerequisites, installs CLI tools, authenticates services, configures git, creates .env, and runs a verification build. Takes about 5 minutes.
What's Different from a "Normal" Dev Setup
The biggest difference: there's no IDE in this workflow. No VS Code, no WebStorm. The entire development loop — reading code, writing components, debugging, committing — happens through Claude Code in the terminal.
This means the setup is actually simpler than most projects. No editor extensions to install, no linter configs to sync, no debugger to attach. Just a terminal, Claude Code, and the CLI tools.
The tradeoff is that your development speed depends on prompt quality. Clear, specific prompts produce better code faster. Vague prompts produce vague code. The skills help by giving Claude Code domain expertise, but the developer's clarity of thought is still the bottleneck — same as it's always been.