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 -pEssential 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-motionimport { 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
vercelConclusion
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! 🚀