My corner of the internet! 🌱
React + TypeScript portfolio site deployed to GitHub Pages with gh-pages.
- Create React App (
react-scripts@5) - React 19 + TypeScript
- React Router (
react-router-dom@7) - Three.js / React Three Fiber
- GSAP (animation)
- Sharp (build time image optimization)
npm start: local dev servernpm run build: production build (runs image optimization first)npm run deploy: publishbuild/to GitHub Pagesnpm run optimize-images: generate optimized image variants + manifestsnpm run lint: run ESLint onsrcnpm run lint:fix: auto fix lint issues where possiblenpm run format: run Prettier on source + docsnpm run format:check: verify formatting
src/app/: route composition and app shell wiringsrc/pages/: page modules (home,portfolio,creative,project-detail,not-found)src/pages/home/: home page feature modules (sections, hooks, concern hooks, events, 3D scene)src/features/: feature folders (currentlybunny/modal + scene system)src/components/: shared site components and visual primitivessrc/components/ui/OptimizedImage.tsx: shared responsive image componentsrc/data/: content data (projects/,awards, photos)src/data/projects/content/: split project content chunks composed intoprojects.content.tssrc/hooks/: reusable cross page hooks (useViewportSize,useMediaQuery,useIntersectionOnce, etc.)src/theme/: tokenized theme values + visual tokensscripts/optimize-images.js: build time image optimizerpublic/optimized/images/: generated responsive assetssrc/generated/imageManifest.json: runtime manifest consumed byOptimizedImage
- Page specific logic stays with the page (for example
src/pages/home/home.hooks.tsandsrc/pages/home/home.concern.hooks.ts). - Cross page hooks live in
src/hooks/. - Complex features are grouped in
src/features/(for example the bunny mini game modal and scene). - Styling is primarily CSS based, with CSS variables used for theme driven and responsive values.
- Add originals to
public/images/...and keep content URLs as/images/.... - Run
npm run optimize-images(or justnpm run build). - Use
OptimizedImageto reuse generatedsrcSet, intrinsic dimensions, and lazy loading behavior. - For heavy GIF thumbnails in grids, set
preferPosterForGifto use generated lightweight posters.