Behind the Scenes: How I Built My Portfolio Website
A deep dive into the design decisions, technology stack, and development process behind creating my personal portfolio website from scratch.
Behind the Scenes: How I Built My Portfolio Website
Building a portfolio website is more than just showcasing your work. it is a reflection of who you are as a developer. Every design decision, every line of code, and every animation tells a story about your craft and attention to detail. In this article, I will take you through the complete journey of building this portfolio from the initial concept all the way to deployment, including the failures, pivots, and breakthroughs along the way.
The Vision
When I first sat down to plan this portfolio, I already knew what I didn't want: a generic template with a hero section, a grid of cards, and a contact form at the bottom. I had seen hundreds of those. What I wanted was something that felt alive. a website that communicated personality before a single word was read.
I started by defining three core principles that would guide every decision:
I spent an entire weekend browsing over 50 developer portfolios, taking screenshots, and noting patterns that worked. Sites like Brittany Chiang's v4 and Lee Robinson's personal site were huge inspirations. not for copying, but for understanding what makes a portfolio feel crafted.
Technology Stack
After researching various options, I chose a modern stack that balances performance, developer experience, and scalability. Here is why each piece was selected:
Frontend Framework: Next.js 14 with App Router
Next.js 14 with the App Router was the clear winner for several reasons. Server Components let me ship zero JavaScript for static sections like the footer, reducing the client bundle significantly. The file-based routing with layouts made it trivial to share a consistent header and footer across pages without prop drilling. And the built-in Image component with automatic optimization meant I could use high-resolution project mockups without worrying about performance.
The App Router's loading.tsx convention was particularly useful. I could show skeleton loaders for each section independently while the full page streamed in, giving users something to see within milliseconds of landing on the page.
Styling: Tailwind CSS
Tailwind CSS became my go-to for styling, and this project solidified that preference. The utility-first approach meant I could iterate on designs directly in JSX without constantly switching between files. But I did not just use raw utilities everywhere. I created a design system layer in globals.css with CSS custom properties for the accent colors, allowing me to later implement a theme switcher between gold and purple palettes with minimal effort.
The responsive design utilities (sm:, md:, lg:, xl:, 2xl:) made it possible to fine-tune the layout at every breakpoint. The hero section, for example, has completely different positioning and typography scales at each breakpoint to ensure it looks intentional on screens ranging from a 375px iPhone SE to a 2560px ultrawide monitor.
Animation: Framer Motion
For animations, I went with Framer Motion. The AnimatePresence component was critical for the tab-switching animations in the Achievements and Involvement section. The whileInView prop made scroll-triggered entrance animations trivial to implement. each card fades in and slides up as it enters the viewport, creating a natural flow as users scroll through content.
One detail I am particularly proud of: the floating skill badges on the hero section. Each badge uses a floatBadge keyframe animation with different delay offsets (0.5s and 2s), so they bob up and down out of sync with each other. It is a tiny detail, but it makes the hero feel dynamic without being distracting.
TypeScript
TypeScript was non-negotiable. Every data model. projects, achievements, professional experiences, blog posts. is strictly typed. This caught dozens of bugs during development, especially when restructuring the project data to support new fields like liveUrl, githubUrl, and category. The type system acts as living documentation: any new developer looking at the codebase can immediately understand the shape of data flowing through each component.
Design Process
The design phase was the most iterative part of the entire project. I did not open Figma and create pixel-perfect mockups first. instead, I designed directly in code, which let me see how things actually felt with real interactions and responsive behavior.
Color System
The primary accent color, a warm gold (#F3CB51), was chosen for its uniqueness in the developer portfolio space (most go for blue or green). Gold conveys premium quality and stands out beautifully against dark backgrounds. The outlined text effect on the hero section (using -webkit-text-stroke) was inspired by luxury fashion brand websites. it gives a bold presence without overwhelming the foreground content.
Later, I implemented a full theme system using CSS custom properties (--theme-accent, --theme-accent-rgb), allowing users to switch between the gold palette and a purple palette (#8B5CF6). This required updating over 20 files to replace hardcoded color values with variables. a lesson in why design tokens should be centralized from day one.
Layout Philosophy
Every section follows a consistent max-width container (max-w-8xl) with responsive padding (px-6 lg:px-8). I avoided full-bleed sections except for the hero and gallery to create a comfortable reading rhythm. The spacing between sections uses a consistent py-12 lg:py-16 pattern that gives each section breathing room without excessive scrolling.
The card designs throughout the site follow a common visual language: dark backgrounds (#1A1A1A), subtle borders (#2A2A2A), and accent-colored hover states that glow on interaction. This consistency makes the entire site feel cohesive even though each section has its own unique layout.
Typography
I chose Poppins as the primary font for its geometric clarity and excellent readability at both display and body sizes. The font weight range (400-700) covers all needs from paragraph text to bold headings. On the hero section, the display text uses fluid sizing with clamp() to scale proportionally between breakpoints rather than jumping at arbitrary cutoffs.
Development Journey
The actual development took about 5 weeks, working on it during evenings and weekends. Here is a rough breakdown of how that time was spent:
Week 1-2: Foundation and Hero
The first two weeks were spent on the project structure, design system, and hero section. Getting the hero right took the longest. the layered composition of background text, photo, floating badges, and foreground content required precise z-index management and absolute positioning that worked across all screen sizes. I probably rebuilt the hero three times before landing on the current layout.
Week 3: Content Sections
Week three was the most productive. Once the design system was established, building the Projects, Professional Experience, and Achievements sections was straightforward. The reusable card patterns and consistent styling utilities meant each section could be built in 1-2 evenings.
The project showcase section went through a major evolution. from simple cards to a full-featured carousel with mockup images, live/GitHub links, and a progress indicator. The tech stack display component supports both wrapped and horizontally scrollable modes depending on context.
Week 4: Blog System and Polish
The blog system was built entirely with static data (no CMS needed for now). Each post is stored as a TypeScript object with markdown content that gets rendered through a custom MarkdownContent component. The blog listing page includes search, category filtering, and a newsletter signup section.
Week 5: Optimization and Deployment
The final week focused on performance tuning, SEO metadata, accessibility improvements, and deployment. I ran Lighthouse audits obsessively, tweaking image sizes, lazy loading boundaries, and font loading strategies until all scores were consistently above 90.
Results
After deployment, the site consistently scores high on Lighthouse performance tests. The Time to First Contentful Paint (FCP) comes in under 1.2 seconds, and the Cumulative Layout Shift (CLS) stays near zero thanks to explicit image dimensions and font-display swap. The total JavaScript bundle for the homepage is under 200KB gzipped. lean enough to load quickly even on 3G connections.
But beyond the metrics, the real result is having a portfolio that I am genuinely proud to share. It represents not just my projects and skills, but my design sensibility, my attention to detail, and my commitment to quality engineering. Every recruiter, collaborator, or fellow developer who visits the site gets an immediate sense of the kind of work I care about building.
Key Takeaways
Building this portfolio taught me several important lessons:
- Start with a design system, not individual pages. Defining your colors, spacing, and component patterns upfront saves hours of refactoring later.
- Invest in responsive design early. Retrofitting responsiveness is painful. Build mobile-first from the start.
- Animations are seasoning, not the main course. A portfolio that animates beautifully but loads slowly is worse than one with no animations at all.
- Ship, then iterate. My first version was rough around the edges, but deploying it early gave me real feedback that shaped the final product.
- Your portfolio is a living document. It should grow and evolve as you do. Do not wait until it is "perfect" to publish it.
Comments
No comments yet. Be the first!
