Back to articles

Building a Personal Portfolio with React and Tailwind CSS

March 15, 2024 (1y ago)

·
3 min read

Your personal portfolio is often the first impression you make on potential employers or clients. In this tutorial, we'll build a modern, responsive portfolio website that showcases your work effectively.

Why React and Tailwind CSS?

This combination offers:

  • Component-based architecture for reusable UI elements
  • Utility-first styling for rapid development
  • Excellent performance with optimized builds
  • Great developer experience with hot reloading

Project Setup

Start by creating a new React project with Vite:

npm create vite@latest my-portfolio -- --template react-ts
cd my-portfolio
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

Essential Portfolio Sections

Every great portfolio should include:

1. Hero Section

Make a strong first impression with a compelling hero:

export function Hero() {
  return (
    <section className="min-h-screen flex items-center justify-center">
      <div className="text-center">
        <h1 className="text-5xl font-bold mb-4">
          Hi, I'm <span className="text-primary">Your Name</span>
        </h1>
        <p className="text-xl text-muted-foreground">
          Full Stack Developer | Open Source Enthusiast
        </p>
      </div>
    </section>
  );
}

2. Projects Showcase

Display your best work with eye-catching project cards:

interface Project {
  title: string;
  description: string;
  image: string;
  tags: string[];
  link: string;
}
 
export function ProjectCard({ project }: { project: Project }) {
  return (
    <div className="rounded-lg border p-4 hover:shadow-lg transition">
      <img src={project.image} alt={project.title} className="rounded-md" />
      <h3 className="text-xl font-semibold mt-4">{project.title}</h3>
      <p className="text-muted-foreground">{project.description}</p>
      <div className="flex gap-2 mt-2">
        {project.tags.map(tag => (
          <span key={tag} className="badge">{tag}</span>
        ))}
      </div>
    </div>
  );
}

3. Skills Section

Highlight your technical expertise:

const skills = [
  { name: "React", level: 90 },
  { name: "TypeScript", level: 85 },
  { name: "Node.js", level: 80 },
  { name: "Tailwind CSS", level: 95 },
];
 
export function Skills() {
  return (
    <section className="py-20">
      <h2 className="text-3xl font-bold mb-8">Skills</h2>
      <div className="grid grid-cols-2 gap-4">
        {skills.map(skill => (
          <div key={skill.name}>
            <div className="flex justify-between mb-1">
              <span>{skill.name}</span>
              <span>{skill.level}%</span>
            </div>
            <div className="h-2 bg-gray-200 rounded">
              <div 
                className="h-full bg-primary rounded"
                style={{ width: `${skill.level}%` }}
              />
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

Adding Animations

Use Framer Motion for smooth animations:

npm install framer-motion
import { motion } from "framer-motion";
 
export function AnimatedSection({ children }) {
  return (
    <motion.div
      initial={{ opacity: 0, y: 20 }}
      whileInView={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.5 }}
      viewport={{ once: true }}
    >
      {children}
    </motion.div>
  );
}

Deployment

Deploy your portfolio to Vercel for free:

npm install -g vercel
vercel

Conclusion

A well-crafted portfolio can open doors to exciting opportunities. Focus on showcasing your best work, keeping the design clean and professional, and ensuring a smooth user experience across all devices.

Happy building! 🚀