Back to all projects
Featured

portfolio

Personal portfolio website built with Next.js 16, showcasing my projects, skills, and career journey as a Full Stack Developer.

TypeScriptUpdated 2/19/2026

Gallery

README

Andres Porras — Portfolio

Personal portfolio website built with Next.js 16, showcasing my projects, skills, and career journey as a Full Stack Developer.

Portfolio Screenshot

Next.js TypeScript Tailwind CSS Framer Motion

Features

  • AI-Powered Terminal — Interactive CLI where visitors can type commands or ask natural language questions about me, powered by Claude Haiku via the Vercel AI SDK
  • Multilingual (EN/FR/ES) — Full internationalization with next-intl, including language switcher and locale-based routing
  • Auto-Fetched Projects — Public GitHub repos pull descriptions, screenshots, and stats directly from the GitHub API and README files via ISR (revalidates hourly)
  • Career Journey Timeline — Animated scroll-linked timeline from Colombia to Canada, built with Framer Motion
  • GitHub Contribution Heatmap — Live coding activity grid using react-github-calendar
  • Dark/Light Mode — Theme toggle powered by next-themes with a dark-first design
  • Contact Form — Server-side email delivery via Resend API with Zod validation
  • SEO Optimized — Structured data (JSON-LD), Open Graph metadata, dynamic sitemap, and robots.txt
  • Fully Responsive — Mobile-first design with glassmorphism navbar and animated mobile menu

Tech Stack

LayerTechnologies
FrameworkNext.js 16 (App Router), React 19, TypeScript
StylingTailwind CSS v4, CSS custom properties, clsx + tailwind-merge
AnimationsFramer Motion (motion package v12)
i18nnext-intl (EN, FR, ES)
AI ChatVercel AI SDK, Anthropic Claude Haiku
ContactResend API, React Hook Form, Zod
IconsLucide React
Themingnext-themes
Markdownreact-markdown, remark-gfm
GitHub DataGitHub REST API with ISR caching, react-github-calendar

Project Structure

portfolio/
├── messages/                    # i18n translation files (en, fr, es)
├── public/
│   ├── images/                  # Profile photo, project screenshots
│   └── resume/                  # Downloadable PDF resume
├── src/
│   ├── app/
│   │   ├── [locale]/            # Locale-wrapped pages
│   │   │   ├── page.tsx         # Main page (all sections)
│   │   │   └── projects/[slug]/ # Dynamic project detail pages
│   │   ├── api/
│   │   │   ├── chat/            # AI terminal chat endpoint
│   │   │   └── contact/         # Contact form email endpoint
│   │   ├── sitemap.ts
│   │   └── robots.ts
│   ├── components/
│   │   ├── layout/              # Navbar, Footer, LanguageSwitcher
│   │   ├── sections/            # Hero, About, Terminal, Journey, Projects, Skills, Education, Contact
│   │   ├── ui/                  # Button, Badge, ContactForm, GitHubHeatmap, StatusBadge, ThemeToggle
│   │   ├── seo/                 # JSON-LD structured data
│   │   └── providers/           # ThemeProvider
│   ├── data/                    # Profile, experience, projects, skills, education, timeline
│   ├── i18n/                    # next-intl routing and request config
│   ├── lib/                     # GitHub API, project resolver, animation variants, utilities
│   └── types/                   # TypeScript interfaces
└── .env.local                   # API keys (not committed)

Getting Started

Prerequisites

  • Node.js 18+
  • npm, yarn, or pnpm

Installation

git clone https://github.com/andresporrasdev/portfolio.git
cd portfolio
npm install

Environment Variables

Create a .env.local file in the root directory:

# Anthropic API key for AI terminal chat
ANTHROPIC_API_KEY=your_anthropic_api_key

# Resend API key for contact form emails
RESEND_API_KEY=your_resend_api_key

# Email address to receive contact form messages
CONTACT_EMAIL=your@email.com

# GitHub token for higher API rate limits (optional)
GITHUB_TOKEN=your_github_token

Development

npm run dev

Open http://localhost:3000 in your browser.

Production Build

npm run build
npm start

Adding Projects

Public GitHub repo — Add one entry to src/data/projects.ts:

{ slug: "my-project", repo: "My-Repo", featured: true, category: "Full Stack" }

All data (description, screenshots, stats) is auto-fetched from the GitHub API and README.

Private or non-GitHub project — Provide full local data:

{
  slug: "my-project",
  title: "My Project",
  description: "Project description",
  techStack: ["React", "Node.js"],
  screenshots: ["/images/projects/my-project.png"],
  liveUrl: "https://my-project.com",
}

License

This project is personal and not open for redistribution. Feel free to use it as inspiration for your own portfolio.