
Building My Portfolio Website
Published on Sun Dec 14 2025
Building My Portfolio Website: Architecture, Tooling & Engineering Decisions
A portfolio site is more than a digital resume — it’s a living system that reflects how you think, design, deploy, and operate software.
In this post, I’ll walk through how I built my personal portfolio website, the architecture behind it, the tooling choices, and the engineering practices I follow to keep it production-grade, even though it’s a “personal” project.
This site is not a static page — it’s a React SPA with serverless backends, CI/CD, monitoring, versioning, and a headless CMS.
Why I Didn’t Go with a Static Site Generator
I intentionally avoided a traditional static site generator.
My goal was to:
- Treat my portfolio like a real production application
- Demonstrate frontend + backend integration
- Practice DevOps workflows on a smaller scale
- Keep content dynamic and extensible
That led me to build the site as a React + Vite SPA, backed by Netlify serverless functions and Sanity CMS.
High-Level Architecture Overview
At a high level, the site consists of:
- Frontend: React SPA (Vite)
- Backend: Netlify serverless functions (Node.js)
- CMS: Sanity.io (headless)
- Hosting: Netlify
- DNS: Cloudflare
- Monitoring: Better Stack
- CI/CD: GitHub Actions + Netlify
- Email & Logs: Resend + Google Sheets
This keeps the system:
- Scalable
- Cost-efficient
- Easy to evolve
Frontend Stack & Site Structure
The frontend is a single-page application built using:
- React + Vite
- Tailwind CSS
- Framer Motion
- React Router
Routing is handled client-side, with a shared layout component wrapping all pages to ensure consistency across the site.
Key routes include:
- Home & About
- Experience & Projects
- Blog (Sanity-powered)
- Consulting (Calendly integration)
- Resume & Contact
- Privacy Policy
Each page is composed using reusable UI primitives such as layout wrappers, SEO helpers, loaders, and animation components, keeping the codebase clean and maintainable
Styling & UI Philosophy
I use Tailwind CSS as a utility-first styling system to avoid:
- CSS bloat
- Over-abstraction
- Hard-to-trace styles
Animations are added using Framer Motion, but deliberately kept subtle:
- Entrance animations
- Hover effects
- Section transitions
The goal is polish, not distraction.
Blogging with Sanity CMS
For content, I wanted full control without redeploying the site every time I publish.
So I chose Sanity.io as a headless CMS.
Sanity stores:
- Blog metadata
- Slugs
- Images
- Rich text content
The frontend fetches blog data dynamically using serverless functions, allowing the blog to scale independently from the UI
This setup lets me:
- Write freely
- Iterate fast
- Keep the frontend stateless
Serverless Backend with Netlify Functions
Instead of a monolithic backend, I use Netlify serverless functions for targeted responsibilities.
Contact & Email Handling
The contact form is powered by a serverless function that:
- Validates inputs
- Blocks disposable email domains
- Uses honeypot fields for bot detection
- Applies spam scoring
- Sends confirmation emails to users
- Sends notification emails to admins
- Logs everything securely
All of this runs without a traditional server, reducing cost and operational overhead
Logging to Google Sheets (Yes, Intentionally)
Instead of setting up a full logging stack, I log structured contact data directly into Google Sheets using a GCP Service Account.
Why?
- Easy audit trail
- Zero dashboard setup
- Accessible anywhere
- Perfect for low-volume, human-readable logs
It’s a pragmatic solution that fits the project’s scale while remaining secure and reliable
Third-Party Integrations That Power the Site
Some key integrations include:
- Resend: Transactional email delivery
- Better Stack: Uptime monitoring and alerts
- Calendly: Consulting session booking
- SonarQube: Code quality analysis
- GitHub Dependabot: Dependency security
- Sanity.io: Content management
Each tool is chosen to solve a specific problem — nothing is added “just because”
Deployment Strategy: Staging vs Production
I maintain two deployment flows:
Staging
- Auto-deploys on any non-main branch
- Used for previews and testing
- Zero manual steps
Production
- Controlled via GitHub Actions
- Runs checks before deployment
- Uses Netlify CLI for publishing
This mirrors real-world DevOps practices and ensures changes are validated before going live
Versioning the Site Like a Real Product
Even though it’s a portfolio, I version it properly.
I follow semantic versioning:
- Patch → bug fixes
- Minor → feature additions
- Major → breaking changes
Version metadata is generated during CI and displayed in the footer with the last updated date.
This helps with:
- Debugging
- Rollbacks
- Transparency
Yes — even portfolios deserve versioning
Monitoring, Quality & Reliability
To keep the site healthy, I rely on:
- Better Stack for uptime checks
- SonarQube for static analysis
- Dependabot for dependency updates
This ensures the codebase stays clean, secure, and reliable over time.
Final Thoughts
This portfolio isn’t just about showing what I’ve done — it’s about how I work.
Every decision reflects:
- Practical engineering
- Cost awareness
- Maintainability
- Production mindset
It’s a small system, but it follows big-system principles.
If you’re curious, the site itself is always evolving — just like the engineer behind it.