Guía paso a paso: crea tu proyecto con Next.js 15

Gabriel Gómez Gómez ·

Guía paso a paso: crea tu proyecto con Next.js 15

  • Vamos a crear un proyecto de Next.js 15 desde cero, eligiendo opciones óptimas para tu stack: JavaScript (sin TypeScript), App Router, carpeta src/, CSS Modules, y ESLint activado. Te explico cada decisión pensando en rendimiento, seguridad y mantenibilidad.

  • 1) Requisitos: Node 20 LTS recomendado (18.18+ funciona), npm (o pnpm), y Git.

  • terminalBASH
    node -v
    npm -v
    git --version
  • 2) Crea el proyecto con create-next-app. Si prefieres responder al asistente interactivo, usa:

  • terminalBASH
    npx create-next-app@latest mi-app
  • Qué elegir en los prompts (recomendado para tu flujo):
    • TypeScript: No (trabajaremos con JavaScript puro, más rápido de montar y suficiente si el equipo no exige TS).
    • ESLint: Sí (consistencia y calidad del código).
    • Tailwind: No (usarás CSS Modules .module.css como prefieres).
    • src/ directory: Sí (estructura limpia y escalable).
    • App Router: Sí (Server Components por defecto, mejor rendimiento y organización).
    • Import alias: Acepta el predeterminado (@/*) para rutas limpias.

  • Si quieres saltarte los prompts, puedes indicar flags comunes (sin forzar Tailwind):

  • terminalBASH
    npx create-next-app@latest mi-app \
      --js \
      --eslint \
      --src-dir \
      --app \
      --import-alias "@/*" \
      --use-npm
  • 3) Entra y ejecuta el servidor de desarrollo:

  • terminalBASH
    cd mi-app
    npm run dev
  • 4) Estructura base (carpeta src/ + App Router). Deberías ver algo similar:

  • estructuraTEXT
    mi-app/
    ├─ public/
    ├─ src/
    │  └─ app/
    │     ├─ favicon.ico
    │     ├─ globals.css
    │     ├─ layout.js
    │     └─ page.js
    ├─ .eslintrc.json
    ├─ jsconfig.json
    ├─ next.config.mjs
    ├─ package.json
    └─ README.md
  • 5) Layout global y metadatos. Usa metadata nativa para SEO y compartir en redes.

  • layout.jsJAVASCRIPT
    // src/app/layout.js
    export const metadata = {
      title: "Mi App | Next.js 15",
      description: "Base con App Router, Server Components y CSS Modules.",
      icons: { icon: "/favicon.ico" },
    };
    
    export default function RootLayout({ children }) {
      return (
        <html lang="es">
          <body>{children}</body>
        </html>
      );
    }
  • 6) Primera página como Server Component (por defecto). Importa un CSS Module para estilos locales y evitar fugas de estilo.

  • page.jsJAVASCRIPT
    // src/app/page.js
    import styles from "./page.module.css";
    
    export default function Home() {
      return (
        <main className={styles.main}>
          <h1>¡Hola Next.js 15!</h1>
          <p>App Router + CSS Modules + Server Components</p>
        </main>
      );
    }
  • page.module.cssCSS
    /* src/app/page.module.css */
    .main {
      min-height: 100dvh;
      display: grid;
      place-items: center;
      text-align: center;
      padding: 2rem;
    }
  • 7) Globals mínimos. Deja solo resets y variables. Evita estilos globales invasivos para no romper módulos.

  • globals.cssCSS
    /* src/app/globals.css */
    :root {
      --vino: #691b32;
      --fg: #111315;
      --bg: #ffffff;
    }
    * { box-sizing: border-box; }
    html, body { margin: 0; padding: 0; color: var(--fg); background: var(--bg); font-family: system-ui, sans-serif; }
    a { color: inherit; text-decoration: none; }
  • 8) Imágenes y estáticos. Guarda tus assets en /public y usa next/image para optimización automática.

  • Logo.jsJAVASCRIPT
    // ejemplo de uso local de imagen
    import Image from "next/image";
    
    export default function Logo() {
      return (
        <Image src="/img/logo.png" alt="Logo" width={160} height={48} priority />
      );
    }
  • 9) Variables de entorno. Nunca expongas secretos en el cliente. Usa .env.local (no se versiona).

  • .env.localBASH
    echo "NEXT_PUBLIC_API_BASE=https://api.midominio.com" >> .env.local
    # Las que NO deben llegar al navegador NO llevan NEXT_PUBLIC_
    # API_SECRET=xxxxx
  • 10) ESLint: activado para mantener calidad. Puedes afinar reglas si lo necesitas.

  • .eslintrc.jsonJSON
    {
      "extends": ["next/core-web-vitals"],
      "rules": {
        "react/no-unescaped-entities": "off"
      }
    }
  • 11) Config opcional de Next (por ejemplo, permitir imágenes remotas). Solo si las usas.

  • next.config.mjsJAVASCRIPT
    // next.config.mjs
    /** @type {import('next').NextConfig} */
    const nextConfig = {
      images: {
        remotePatterns: [
          { protocol: "https", hostname: "images.unsplash.com" }
        ]
      }
    };
    export default nextConfig;
  • 12) Rutas y segmentación. Con App Router, cada carpeta en src/app es una ruta. Crea /src/app/(public)/about/page.js para agrupar rutas públicas, y usa Server Components siempre que no necesites estado/efectos del cliente.

  • about/page.jsJAVASCRIPT
    // src/app/(public)/about/page.js
    export default function AboutPage() {
      return <h2>Acerca de</h2>;
    }
  • 13) Componentes de Cliente solo cuando sea necesario (interactividad, efectos, refs). Al inicio del archivo añade "use client".

  • Counter.jsJAVASCRIPT
    "use client";
    import { useState } from "react";
    
    export default function Counter() {
      const [n, setN] = useState(0);
      return <button onClick={() => setN(n+1)}>Clicks: {n}</button>;
    }
  • 14) Scripts útiles (build y producción). En dev puedes probar Turbopack opcionalmente.

  • terminalBASH
    npm run build
    npm run start
    # Opcional en desarrollo:
    # next dev --turbo
  • 15) Buenas prácticas de arquitectura (resumen):
    • Server Components por defecto: menos JS en el cliente, cargas más rápidas.
    • Encapsula estilos con .module.css para evitar colisiones.
    • Fetch en el servidor con caché adecuada (revalidate, cache: 'no-store' donde aplique).
    • Nunca expongas secretos en NEXT_PUBLIC_.
    • Segmenta rutas por dominio (p. ej., (public), (dashboard)).
    • Desacopla UI y datos: componentes puros + funciones de acceso a datos.