A personal portfolio and blog website built with Next.js 16, Payload CMS 3, TypeScript, Motion, and TailwindCSS v4.
- Framework: Next.js 16 (App Router)
- CMS: Payload CMS 3 with Lexical editor
- Database: PostgreSQL
- Styling: TailwindCSS v4
- Animations: Motion (Framer Motion)
- State Management: Zustand
- Media Storage: Vercel Blob
- PDF Rendering: React PDF
- Deployment: Docker / Vercel
- Node.js >= 20
- pnpm
- PostgreSQL (or a remote database URL)
- Vercel Blob token (for media uploads)
git clone https://github.com/<username>/portfolio.git
cd portfoliopnpm installCopy the example env file and fill in the values:
cp .env.example .envRequired variables:
| Variable | Description |
|---|---|
DATABASE_URL |
PostgreSQL connection string |
PAYLOAD_SECRET |
Secret key for Payload CMS |
BLOB_READ_WRITE_TOKEN |
Vercel Blob storage token |
NEXT_PUBLIC_MEDIA_STORAGE_URL |
Base URL for media assets |
Ensure your PostgreSQL database is running and the DATABASE_URL in .env points to it. Payload will handle migrations on first run.
pnpm devThe app will be available at http://localhost:3000.
The Payload admin panel is available at http://localhost:3000/admin.
portfolio/
├── app/
│ ├── (frontend)/ # Public-facing pages
│ ├── (payload)/ # Payload CMS admin & API routes
│ └── globals.css # Global styles
├── components/ # Reusable React components
├── content/ # Static content / data
├── hooks/ # Custom React hooks
├── payload/
│ ├── blocks/ # Payload block definitions
│ ├── collections/ # Payload collections (Blogs, Media, Users, etc.)
│ ├── fields/ # Custom Payload fields
│ └── globals/ # Payload globals
├── utils/ # Utility functions
├── payload.config.ts # Payload CMS configuration
├── next.config.ts # Next.js configuration
└── Dockerfile # Multi-stage Docker build (Bun)
| Command | Description |
|---|---|
pnpm dev |
Start the development server |
pnpm build |
Build for production |
pnpm start |
Start the production server |
pnpm lint |
Run ESLint |
pnpm generate:types |
Generate Payload TypeScript types |
pnpm generate:importmap |
Generate Payload import map |
Build and run with Docker using the included multi-stage Dockerfile (Bun-based):
docker build -t portfolio .
docker run -p 3000:3000 --env-file .env portfolioPrivate — All rights reserved.