Creating a personal portfolio that blends music, visual art, and technology into one seamless experience was both thrilling and challenging. In this post, I’ll share the journey of building this site; from picking the stack to deploying it live.

Technology Stack

I built this portfolio with performance, flexibility, and aesthetics in mind:

  • Framework: Next.js (v15) for hybrid rendering and seamless routing.
  • Language: TypeScript to catch bugs early and improve dev speed.
  • Styling: Tailwind CSS for utility-first styling and responsive design.
  • Content: Markdown, powered by Gray Matter for metadata and remark for rendering.
  • Audio: WaveSurfer.js for interactive, customizable audio players.
  • Deployment: Vercel with GitHub integration for instant CI/CD workflows.

Key Features

  • Markdown Blog: Dynamic routes, metadata support, and tag filtering.
  • Music Section: Waveform audio previews, collapsible lyrics, and release metadata.
  • Art Gallery: Responsive layouts showcasing digital and traditional works.
  • Theme Toggle: Light, Dark, Ocean, and more—customized via Tailwind config.
  • Fully Responsive: Tailored UI for mobile, tablet, and desktop users.

Development Process

1. Setting Up the Project

npx create-next-app@latest portfolio --typescript

This bootstrapped a modern Next.js 15 project with TypeScript support right out of the gate.

2. Styling with Tailwind CSS

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init

Then I extended the tailwind.config.js to include custom color themes and breakpoints.

3. Blog Functionality

Each post is written in Markdown with front matter:

---
title: "Post Title"
excerpt: "Short description of the post."
tags: ["Tag1", "Tag2"]
category: "Category"
---

gray-matter parses this data, while remark handles the rendering pipeline.

4. Music Portfolio

Using WaveSurfer.js, I added waveform-based audio players with custom themes:

import WaveSurfer from "wavesurfer.js";

const waveform = WaveSurfer.create({
  container: "#waveform",
  waveColor: "#7c3aed",
  progressColor: "#9333ea",
  height: 80,
  responsive: true,
});

I eventually deprecated this feature, but found it fun to implement at the time.

5. Deployment with Vercel

Integrated with GitHub for continuous deployment:

git push origin main

Each push triggers an automatic build and deploy on Vercel.

Challenges and Lessons Learned

  • Dynamic Routing: Next.js dynamic routes made things modular, but organizing slugs and file structures early was crucial.
  • Type Safety: TypeScript's benefits really showed up in edge cases; worth the learning curve.
  • Performance: Lazy loading images and audio components helped keep things snappy, even on slower connections.
  • Content Management: Writing posts in Markdown worked well, but abstracting logic for front matter handling saved me headaches later.

Conclusion

This portfolio is more than a website; it's a reflection of my work, identity, and growth. Whether you're a developer, artist, or curious visitor, I hope this breakdown helps you craft something of your own.

Dive into the source code on GitHub, remix it, or reach out if you'd like to chat more.