Lo que tu portfolio dice de ti antes de que digas una sola palabra
Un reclutador pasa de media 6 segundos en un CV. En un portfolio en línea, es incluso menos — a menos que algo llame su atención.
La mayoría de los portfolios de desarrollador se parecen. Misma estructura. Misma sección “Sobre mí”. Misma lista de habilidades en insignias de colores. Mismo formulario de contacto al final de la página. Si usas un template genérico sin retocar, no destacas — te fundes con la masa.
La pregunta real: ¿cómo construir un template de portfolio que siga siendo profesional, rápido de personalizar, y que dé ganas de hacer scroll hasta el final?
Esto es lo que hemos aprendido construyendo e industrializando proyectos frontend con React, Vite y Tailwind. Decisiones técnicas, errores evitados, patrones que realmente funcionan.
Por qué React + Vite + Tailwind es el stack que tiene sentido en 2025
No es un stack de moda. Es un stack pragmático.
React para la composabilidad. Un portfolio es una colección de secciones reutilizables: Hero, Proyectos, Habilidades, Contacto. React te obliga a pensar en componentes — y eso es exactamente lo que se necesita para un template personalizable.
Vite para la velocidad. El tiempo de inicio en desarrollo es casi instantáneo comparado con Create React App. Hot Module Replacement reactivo, build de producción optimizado, cero configuración innecesaria. En un proyecto en solitario como un portfolio, cada minuto de fricción cuenta.
Tailwind CSS para la eficiencia en los estilos. No hay que hacer malabares entre un archivo .jsx y un archivo .css para cada componente. Las clases utilitarias están directamente en el markup. Resultado: ves el estilo en el mismo lugar que la estructura. Y la personalización se hace cambiando algunos valores en tailwind.config.js, no buscando variables CSS dispersas en 12 archivos.
La combinación de los tres da un workflow de desarrollo fluido, un bundle final ligero y una base fácil de mantener o transferir. Para un sitio más orientado al contenido, una alternativa como Astro y su enfoque de cero JS por defecto también merece la pena — cada stack tiene su propio terreno de juego.
Arquitectura del proyecto: las decisiones que lo cambian todo
El primer error de un template de portfolio es poner todo en App.jsx. Un archivo de 800 líneas donde todo está mezclado — datos, lógica, renderizado. Imposible de mantener. Imposible de personalizar sin romper todo.
La estructura que funciona se ve así:
src/
├── components/ # Componentes UI reutilizables
├── sections/ # Secciones de la página (Hero, Projects, etc.)
├── data/ # Archivos de configuración (JSON o JS)
├── hooks/ # Hooks personalizados (useDarkMode, useScrollSpy...)
└── assets/ # Imágenes, iconos
La separación datos / componentes es innegociable.
Toda la personalización debe pasar por los archivos de data/. Nombre, título, proyectos, enlaces a redes sociales, habilidades — todo eso en un archivo config.js o portfolio.json. Alguien que quiera adaptar tu template no debería tener que tocar nunca un componente React.
Esa es la diferencia entre un template que la gente realmente usa y uno que abandona tras 20 minutos de frustración.
Ejemplo concreto de archivo de configuración
// src/data/config.js
export const siteConfig = {
name: "Marie Dupont",
title: "Desarrolladora Full-Stack",
location: "Caen, Normandía",
email: "contact@mariedupont.dev",
bio: "Construyo interfaces rápidas y accesibles.",
social: {
github: "https://github.com/mariedupont",
linkedin: "https://linkedin.com/in/mariedupont"
}
}
Limpio. Legible. Modificable en 2 minutos sin tocar el código React.
Modo oscuro: implementarlo sin crearse problemas
El modo oscuro es esperado. En un portfolio tech, no tenerlo es una señal negativa.
Pero implementarlo con Tailwind requiere una decisión arquitectónica desde el principio: estrategia class o estrategia media.
La estrategia media sigue automáticamente las preferencias del sistema. Simple, pero pierdes el control del usuario — imposible añadir un toggle.
La estrategia class es el enfoque correcto para un portfolio. Añades o eliminas la clase dark en el elemento <html>, y Tailwind aplica las variantes dark:. El usuario puede cambiar manualmente, y la preferencia se persiste en localStorage.
// src/hooks/useDarkMode.js
import { useState, useEffect } from 'react'
export function useDarkMode() {
const [isDark, setIsDark] = useState(() => {
return localStorage.getItem('theme') === 'dark' ||
window.matchMedia('(prefers-color-scheme: dark)').matches
})
useEffect(() => {
document.documentElement.classList.toggle('dark', isDark)
localStorage.setItem('theme', isDark ? 'dark' : 'light')
}, [isDark])
return [isDark, setIsDark]
}
Este hook hace exactamente lo que se necesita. Nada más. Ese es el principio: no sobre-ingeniería.
En tailwind.config.js, recuerda activar:
darkMode: 'class'
Y en tus componentes, las clases dark: hacen el resto:
<section className="bg-white dark:bg-gray-900 text-gray-900 dark:text-white">
Responsividad: pensar mobile-first de verdad
“Mobile-first” es un principio que todo el mundo conoce y que la mitad de los desarrolladores aplica al revés.
Con Tailwind, mobile-first es concreto: escribes los estilos base para móvil, luego añades breakpoints para pantallas más grandes con los prefijos sm:, md:, lg:.
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
Un error recurrente: las imágenes. Una imagen Hero de 1920px cargada en móvil son 3 segundos de carga perdidos. Usa sistemáticamente el formato WebP, y aprovecha el componente <picture> o las props srcSet para servir el tamaño correcto en la pantalla correcta.
En un portfolio, el rendimiento también es una demostración de competencias. Un Lighthouse score por debajo de 90 es un argumento en tu contra. Las tendencias del diseño web y el CSS moderno muestran además cómo conseguir efectos cuidados sin sobrecargar el renderizado.
“La velocidad de un sitio no es solo un criterio técnico — es un argumento comercial. Google lo mide, los usuarios lo sienten, y tus clientes potenciales sacan conclusiones sobre tu seriedad.” — Lo que llevamos 15 años diciéndole a nuestros clientes en GDM-Pixel.
Los errores clásicos que vemos demasiado a menudo
Tras auditar y refactorizar decenas de proyectos frontend, los mismos errores se repiten.
La animación por la animación. Transiciones en cada elemento, efectos de scroll por todas partes, partículas de fondo. Resultado: el portfolio es lento, distractor, y da la impresión de que el desarrollador no sabe tomar decisiones. Menos es más. Una animación bien colocada vale más que 10 animaciones al azar.
Los datos codificados dentro de los componentes. Lo mencionamos, pero es tan frecuente que merece repetirse. Si tu título está escrito directamente en el JSX del componente Hero, tu template no es un template — es un sitio personal disfrazado.
La ausencia de gestión de estado en el formulario de contacto. Un formulario sin retroalimentación visual (cargando, éxito, error) es una mala UX. Usa useState para gestionar los estados del formulario. Integra un servicio como Resend, EmailJS o Formspree para el envío — no hace falta ningún backend personalizado.
La falta de accesibilidad. Aria-labels faltantes en los iconos, contraste insuficiente entre texto y fondo, navegación por teclado imposible. En un portfolio de desarrollador, esto es especialmente visible — y especialmente mal percibido por quien recluta.
Personalización rápida: lo que debe ser configurable
Un buen template de portfolio debe permitir a alguien personalizarlo completamente en menos de una hora. Esto es lo que absolutamente debe estar en los archivos de configuración, no en el código:
La paleta de colores principal. En tailwind.config.js, define un color primary que se propague por todas partes:
theme: {
extend: {
colors: {
primary: '#6366f1', // Cambia solo esta línea
}
}
}
Las fuentes. Google Fonts importado en index.css, referenciado en la configuración de Tailwind. Cambiar una fuente = dos líneas modificadas.
Los proyectos, habilidades, experiencias. Todo en arrays en data/. Añadir un proyecto = añadir un objeto a un array. Nada más.
Lo que este tipo de proyecto realmente te enseña
Construir un template de portfolio con este stack es un excelente ejercicio de disciplina.
Te ves obligado a tomar decisiones de arquitectura en un proyecto de pequeña escala. Separación de responsabilidades, gestión de estado, accesibilidad, rendimiento — todo eso en un perímetro manejable. Es el mejor campo de aprendizaje.
Tres aprendizajes concretos:
1. La configuración antes que el código. Cuanto más configurable sea tu template sin tocar el código React, más valor tiene. Para ti y para los demás.
2. El rendimiento no es opcional. En un portfolio tech, un sitio lento es un contraargumento directo a tus competencias. Vite + imágenes optimizadas + code splitting mínimo es la base.
3. El modo oscuro y la responsividad no son extras. Son requisitos básicos en 2025. Implementarlos desde el principio cuesta menos que añadirlos después.
Conclusión: un template es un producto — trátalo como tal
Un portfolio de desarrollador no es solo un escaparate. Es una demostración activa de tus decisiones técnicas, tu sentido de la organización y tu atención al detalle.
Con React, Vite y Tailwind, tienes todas las herramientas para entregar algo limpio, rápido y verdaderamente personalizable. El stack no es la dificultad — son la arquitectura y las decisiones del design system las que marcan la diferencia.
En GDM-Pixel, aplicamos estos mismos principios en nuestros proyectos de clientes: separación de datos, componentes reutilizables, configuración centralizada. Lo que funciona en un portfolio funciona en una aplicación de negocio, y es exactamente el rigor que ponemos en cada creación de sitio web profesional. Por eso hemos industrializado nuestro workflow en torno a estos patrones.
¿Estás trabajando en un proyecto frontend y buscas estructurar tu stack o acelerar tu producción? Habla con nosotros — miramos concretamente qué se puede optimizar en tu workflow, sin venderte una renovación completa si no es necesario.
Fuentes y recursos para profundizar: Documentación oficial de Vite, Tailwind CSS Dark Mode, Documentación de React — Thinking in React