Back to Blog
Tech10 February 20267 min read

Building My Portfolio with Claude Code and Skills.sh

How I used Claude Code and Skills.sh agent skills to build a Next.js portfolio site from scratch -- what worked, what surprised me, and honest takeaways.

I built this entire portfolio site using Claude Code and a handful of agent skills from Skills.sh. Not as a gimmick or a flex -- I genuinely wanted to see how far AI-assisted development could take a real project. Here's how it went.

What Are Claude Code and Skills.sh?

Claude Code is Anthropic's CLI tool for working with Claude directly in your terminal. Instead of copy-pasting code between a chat window and your editor, Claude Code reads your files, understands your project structure, and makes changes in place. It's like pair programming with someone who never gets tired and has read every Stack Overflow answer ever written.

Skills.sh is a marketplace of agent skills that plug into Claude Code. Think of them as specialised instruction sets. Instead of Claude Code winging it, you give it domain expertise -- a Next.js skill that knows about App Router conventions, a Tailwind skill that understands design systems, an animation skill that writes proper Framer Motion code. They're community-built and surprisingly good.

Why I Chose AI-Assisted Development

I'm a Technical Provisioning Engineer with nine years in IT. I know networking, I know infrastructure, and I've been teaching myself to code. But I'm not a senior frontend developer. Building a polished portfolio site from scratch -- with animations, a blog system, a gallery, responsive design, dark theming -- would normally take me weeks of fumbling through documentation.

With Claude Code, I figured I could move faster and learn in the process. Not by letting AI do everything blindly, but by working alongside it. I'd describe what I wanted, review what it produced, ask questions when I didn't understand something, and iterate.

That's roughly what happened. With some surprises along the way.

Skills That Made the Difference

Next.js and App Router

The Next.js skill was the backbone. It knew the difference between server and client components, handled the App Router file conventions correctly, and stopped me from making mistakes I wouldn't have caught until build time. Things like accidentally using hooks in a server component or getting the async route params wrong in Next.js 16. The skill flagged these before they became problems.

Tailwind Design System

I had a colour palette in mind -- deep purples, near-black backgrounds, lavender accents -- but turning that into a coherent design system with CSS custom properties, dark mode variables, and consistent spacing was not my strong suit. The Tailwind skill helped me set up the theme in globals.css using Tailwind v4's @theme syntax, which was new to me. It also kept component styling consistent without me having to constantly reference a style guide.

Animation and SEO

The Framer Motion skill produced scroll-triggered animations that actually perform well. Staggered fade-ups, viewport-aware transitions, the kind of subtle motion that makes a portfolio feel polished without being obnoxious. I'd tried writing these by hand before and ended up with janky, layout-thrashing messes.

For blog content, the SEO skill helped me think about structure, keyword placement, and meta descriptions in a way I wouldn't have on my own. I'm a developer, not a content marketer.

What Worked

Speed was the obvious win. I went from an empty Next.js scaffold to a fully functional portfolio with blog, gallery, contact form, and interactive particle animation in a fraction of the time it would have taken me solo. Claude Code didn't just write code -- it understood context. When I said "add a gallery section that fetches from R2," it looked at my existing R2 utility, followed the same patterns, and produced something that fit.

Learning was the unexpected win. I actually understood more of what was happening than when I followed tutorials. Claude Code explained its choices when I asked. Why use viewport={{ once: true }} on animations? Why separate the gallery into a server component and a client wrapper? These micro-explanations, delivered in context while I was building, stuck better than any course.

Consistency was the quiet win. Every component followed the same patterns. Same animation approach, same spacing conventions, same import structure. When you're building alone, consistency is the first thing to slip. Having an AI that remembers your conventions is genuinely useful.

What Didn't Work (Or Needed Fixing)

It's not magic. Claude Code occasionally generated code that looked right but had subtle issues. A TypeScript type that was slightly wrong. An animation that triggered on every scroll instead of once. An R2 utility that didn't handle missing environment variables gracefully. You still need to read the code, test it, and think critically.

Over-engineering was a recurring temptation. Claude Code sometimes wanted to add error boundaries, loading states, and fallback UI for scenarios that didn't apply to my simple portfolio. I had to actively say "keep it simple" and resist the urge to accept every suggestion.

Skills aren't perfect either. A couple of times, skill instructions conflicted with each other or with newer library versions. The fix was usually straightforward, but it's a reminder that these tools augment your judgement -- they don't replace it.

The Numbers

For context, this site includes:

  • Interactive particle network canvas animation
  • Responsive navigation with mobile drawer
  • Project grid with hover effects
  • Blog system with MDX rendering, fetched from Cloudflare R2
  • Image gallery with drag-scroll strips, also from R2
  • Contact form with Zod validation
  • Dark theme with custom CSS properties
  • Scroll-triggered animations throughout

That's a non-trivial amount of work. Could I have built it without AI tools? Yes, eventually. Would it have been as polished or as consistent? Honestly, probably not.

Would I Do It Again?

Without hesitation. Claude Code with Skills.sh is now my default workflow for new projects. Not because it writes perfect code -- it doesn't -- but because it raises my ceiling. I can attempt more ambitious things and actually finish them.

The key insight is that AI-assisted development works best when you stay engaged. Review everything. Ask why. Push back when something feels wrong. The tool gets better when you treat it like a collaborator rather than an oracle.

If you're on the fence about trying Claude Code, my advice is to start with a real project. Not a tutorial, not a toy app. Something you actually want to build. That's where the value becomes obvious.