Personal portfolio site built with Astro and deployed on Cloudflare Workers.
- Zero-JS baseline — Astro renders static HTML; JavaScript is only shipped for the interactive typing test via a React island (
client:idle) - Interactive typing test — A Monkeytype-inspired game built with React 19 + Zustand, featuring real-time WPM/accuracy tracking, tape mode, and keyboard shortcuts; render-optimized so each keystroke re-renders only the affected letter component
- Live GitHub data — Repository stats (recent commits, language breakdown, lines changed) fetched via Astro Server Islands — Astro's equivalent of Next.js async Server Components — with Cloudflare CDN caching and skeleton loading states
- 4-flavor Catppuccin theming — Full light/dark theme support (Latte, Frappe, Macchiato, Mocha) with 14 selectable accent colors, respecting OS color scheme preference
- Accessibility-first — Semantic HTML, ARIA labels/live regions, full keyboard navigation, and
prefers-reduced-motionsupport
| Layer | Technology |
|---|---|
| Framework | Astro 6 |
| Interactive UI | React 19 (with Compiler) |
| State Management | Zustand 5 |
| Styling | Tailwind CSS 4, tailwind-variants |
| Components | Starwind UI |
| Icons | Tabler Icons |
| Font | Maple Mono |
| Deployment | Cloudflare Workers |
| Testing | Vitest 4 |
| Linting | ESLint 10, Prettier, CommitLint |
src/
├── components/
│ ├── react/ # React islands (typing test game)
│ ├── sections/ # Page sections (hero, work, beyond-work)
│ ├── starwind/ # Starwind UI components
│ └── ui/ # Shared utility components
├── data/ # Global/shared data (contact info, git config)
├── layouts/ # Root layout, header, footer
├── lib/
│ ├── cache/ # Cloudflare CDN cache helpers
│ └── github/ # GitHub API queries and types
├── pages/ # Single-page entry (index.astro)
└── styles/ # Catppuccin theme, Tailwind config, fonts
Feature-specific data is co-located with its component in data.ts files (e.g., work experience data lives in sections/work-section/work-experience-section/data.ts).
# Install dependencies
pnpm install
# Start dev server at localhost:4321
pnpm dev
# Production build
pnpm build
# Preview production build
pnpm preview| Variable | Required | Description |
|---|---|---|
GITHUB_TOKEN |
No | GitHub personal access token for higher API rate limits |
# Typecheck + test + format + lint
pnpm diagnose
# Same with auto-fix
pnpm diagnose --fix
# Run tests
pnpm test
# Run tests in watch mode
pnpm test:watchThe project enforces Conventional Commits via CommitLint and runs lint-staged checks on pre-commit through Husky.
- Color palette: Catppuccin
- Font: Maple Mono
- Icons: Tabler Icons
- Design inspiration: Jason Cameron, Duy Le, Brittany Chiang