Back

Cómo Crear y Publicar un Paquete npm

Cómo Crear y Publicar un Paquete npm

Has instalado cientos de paquetes con npm install. Ahora quieres publicar el tuyo propio. El proceso parece sencillo hasta que descubres tutoriales obsoletos que recomiendan Node 12, configuraciones exclusivas de CommonJS y tokens de larga duración almacenados en secretos de CI.

Esta guía te llevará paso a paso por la creación y publicación de un paquete npm utilizando prácticas modernas y seguras que seguirán siendo correctas en 2025. Construiremos una utilidad simple, la configuraremos adecuadamente y la publicaremos con npm Trusted Publishing.

Puntos Clave

  • Usa ESM con el campo exports adecuado en lugar del campo legacy main para una resolución moderna de paquetes
  • Compila TypeScript a JavaScript con archivos de declaración en lugar de distribuir TypeScript sin procesar
  • Habilita la autenticación de dos factores y usa npm Trusted Publishing mediante OIDC de GitHub Actions para lanzamientos automatizados seguros
  • Siempre verifica el contenido de tu paquete con npm pack --dry-run antes de publicar

Requisitos Previos

Antes de comenzar, asegúrate de tener:

  • Node.js 18 o posterior instalado
  • Una cuenta de GitHub
  • Familiaridad básica con npm como consumidor

Inicializa tu Configuración de Paquete npm con ESM como Prioridad

Crea un nuevo directorio e inicializa tu proyecto:

mkdir use-toggle && cd use-toggle
npm init -y
git init

Construiremos un hook simple de React llamado useToggle. Este ejemplo demuestra la publicación de paquetes npm en TypeScript con puntos de entrada adecuados.

Configura package.json para Publicación Moderna

Reemplaza tu package.json con una versión configurada correctamente:

{
  "name": "@yourusername/use-toggle",
  "version": "0.1.0",
  "description": "A simple React hook for boolean toggle state",
  "keywords": ["react", "hook", "toggle", "state"],
  "license": "MIT",
  "author": "Your Name",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/yourusername/use-toggle.git"
  },
  "type": "module",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "files": ["dist"],
  "engines": {
    "node": ">=18"
  },
  "peerDependencies": {
    "react": ">=18"
  },
  "devDependencies": {
    "typescript": "^5.4.0",
    "react": "^18.0.0",
    "@types/react": "^18.0.0"
  },
  "scripts": {
    "build": "tsc",
    "prepublishOnly": "npm run build"
  }
}

Puntos clave para esta configuración de paquete npm con ESM como prioridad:

  • type: "module" declara ESM como predeterminado
  • exports reemplaza el campo legacy main—así es como Node moderno resuelve los puntos de entrada
  • files controla qué se publica (solo dist/)
  • engines especifica Node 18+, evitando problemas de compatibilidad legacy

Configura la Compilación de TypeScript

Crea tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "declaration": true,
    "outDir": "dist",
    "rootDir": "src",
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["src"]
}

Crea src/index.ts:

import { useState, useCallback } from 'react';

export function useToggle(initial = false): [boolean, () => void] {
  const [value, setValue] = useState(initial);
  const toggle = useCallback(() => setValue(v => !v), []);
  return [value, toggle];
}

Ejecuta npm run build para compilar. Obtendrás dist/index.js y dist/index.d.ts—JavaScript más declaraciones de tipos, no TypeScript sin procesar.

Publicación Segura de Paquetes npm en 2025

Crea tu Cuenta npm con 2FA

  1. Regístrate en npmjs.com
  2. Habilita la autenticación de dos factores inmediatamente (preferiblemente WebAuthn/passkeys)
  3. Todos los paquetes nuevos ahora tienen la aplicación de 2FA habilitada por defecto
  4. Con el nuevo modelo de inicio de sesión basado en sesiones, publicar cualquier paquete—nuevo o existente—requiere 2FA durante la sesión

Tu Primera Publicación Manual

npm login ahora crea un token de sesión de dos horas. Estos tokens:

  • No aparecen en la interfaz de npm
  • Expiran automáticamente después de dos horas
  • No pueden reutilizarse en CI/CD
  • Siempre aplican 2FA antes de publicar

Las herramientas antiguas que se autentican mediante el endpoint obsoleto de CouchDB también reciben tokens de sesión de dos horas durante el período de transición.

Para tu lanzamiento inicial:

npm login
npm publish --access public

La bandera --access public es requerida para paquetes con scope en cuentas gratuitas.

Verifica tu paquete en https://www.npmjs.com/package/@yourusername/use-toggle.

npm Trusted Publishing con CI

Los tutoriales antiguos te dicen que crees un NPM_TOKEN y lo almacenes como secreto del repositorio. Este enfoque ahora está obsoleto: los tokens clásicos han sido revocados permanentemente, y los tokens de CI de larga duración ya no son compatibles.

La alternativa moderna es npm Trusted Publishing mediante OIDC de GitHub Actions. GitHub demuestra su identidad a npm, y npm emite credenciales de corta duración automáticamente—sin necesidad de token almacenado.

Configura Trusted Publishing

  1. En npmjs.com, ve a tu paquete → Settings → Publishing access
  2. Agrega un nuevo “Trusted Publisher” con los detalles de tu repositorio de GitHub

Crea el Workflow

Agrega .github/workflows/publish.yml:

name: Publish

on:
  release:
    types: [published]

jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '22'
          registry-url: 'https://registry.npmjs.org'
      - run: npm ci
      - run: npm publish --provenance --access public

La bandera --provenance agrega atestación criptográfica que vincula tu paquete con su repositorio de origen—una característica de seguridad de la cadena de suministro que npm introdujo en 2023.

Si OIDC no puede usarse (por ejemplo, runners auto-hospedados), crea un token de acceso granular de corta duración usando:

npm token create

Los tokens granulares pueden optar por Bypass 2FA para publicación en CI y deben expirar dentro de 90 días.

Lo que Verás en Tutoriales Antiguos

Evita estos patrones obsoletos:

  • "main": "index.js" sin exports—usa exports para una resolución ESM adecuada
  • Apuntar a Node 10/12/14—Node 18+ es compatible, pero los paquetes nuevos deben apuntar a versiones LTS modernas (Node 20 o 22)
  • Paquetes exclusivos de CommonJS—ESM es el estándar; distribuye con ESM como prioridad
  • NPM_TOKEN permanente en cada workflow—los tokens clásicos están completamente revocados; usa Trusted Publishing sin tokens

Verifica Antes de Publicar

Siempre prueba tu paquete localmente antes de publicar:

npm pack --dry-run

Esto muestra exactamente qué archivos se incluirán. Si ves src/ o node_modules/, tu campo files necesita ajustes.

Conclusión

Para crear y publicar un paquete npm en 2025: usa ESM con exports adecuado, compila TypeScript a JavaScript con declaraciones, habilita 2FA y automatiza los lanzamientos con npm Trusted Publishing. Omite los patrones legacy—causarán dolores de cabeza para ti y tus usuarios.

Preguntas Frecuentes

Publica JavaScript compilado con archivos de declaración. Distribuye la carpeta dist que contiene tu JS compilado y archivos .d.ts generados. Esto asegura compatibilidad entre diferentes versiones de TypeScript y herramientas de compilación. TypeScript sin procesar obliga a los consumidores a compilar tu código, lo que puede causar conflictos de versión y compilaciones más lentas.

Usa dependencies para paquetes que tu código empaqueta y distribuye. Usa peerDependencies para paquetes que los consumidores deben proporcionar, como React para un hook de React. Esto previene copias duplicadas de bibliotecas grandes en el bundle final. Tu paquete espera la versión del consumidor en lugar de empaquetar la suya propia.

Los paquetes con scope como @username/package-name son privados por defecto en npm. Las cuentas gratuitas de npm no pueden publicar paquetes privados, por lo que debes establecer explícitamente --access public. Esta bandera le dice a npm que publique el paquete públicamente. Solo la necesitas para la primera publicación; las versiones subsiguientes heredan el nivel de acceso.

Usa npm deprecate @scope/package para advertir a los usuarios sin eliminar el paquete. La despublicación completa con npm unpublish está restringida a paquetes publicados dentro de las 72 horas o aquellos con descargas mínimas. Para paquetes abandonados, se prefiere la deprecación ya que advierte a los usuarios mientras preserva las instalaciones existentes.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay