Comment créer et publier un package npm
Vous avez installé des centaines de packages avec npm install. Maintenant, vous voulez publier le vôtre. Le processus semble simple jusqu’à ce que vous découvriez des tutoriels obsolètes recommandant Node 12, des configurations CommonJS uniquement, et des tokens à longue durée de vie stockés dans les secrets CI.
Ce guide vous accompagne dans la création et la publication d’un package npm en utilisant des pratiques modernes et sécurisées qui resteront valables en 2025. Nous allons créer un utilitaire simple, le configurer correctement et le publier avec npm Trusted Publishing.
Points clés à retenir
- Utilisez ESM avec un champ
exportsapproprié au lieu du champmainobsolète pour une résolution moderne des packages - Compilez TypeScript en JavaScript avec des fichiers de déclaration plutôt que de livrer du TypeScript brut
- Activez l’authentification à deux facteurs et utilisez npm Trusted Publishing via GitHub Actions OIDC pour des releases automatisées sécurisées
- Vérifiez toujours le contenu de votre package avec
npm pack --dry-runavant publication
Prérequis
Avant de commencer, assurez-vous d’avoir :
- Node.js 18 ou ultérieur installé
- Un compte GitHub
- Une connaissance de base de npm en tant qu’utilisateur
Initialiser la configuration de votre package npm ESM-first
Créez un nouveau répertoire et initialisez votre projet :
mkdir use-toggle && cd use-toggle
npm init -y
git init
Nous allons créer un hook React simple appelé useToggle. Cet exemple démontre la publication d’un package npm TypeScript avec des points d’entrée appropriés.
Configurer package.json pour une publication moderne
Remplacez votre package.json par une version correctement configurée :
{
"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"
}
}
Points clés pour cette configuration de package npm ESM-first :
type: "module"déclare ESM comme format par défautexportsremplace le champmainobsolète — c’est ainsi que Node moderne résout les points d’entréefilescontrôle ce qui est publié (uniquementdist/)enginesspécifie Node 18+, évitant les problèmes de compatibilité avec les versions obsolètes
Configurer la compilation TypeScript
Créez tsconfig.json :
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"declaration": true,
"outDir": "dist",
"rootDir": "src",
"strict": true,
"skipLibCheck": true
},
"include": ["src"]
}
Créez 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];
}
Exécutez npm run build pour compiler. Vous obtiendrez dist/index.js et dist/index.d.ts — du JavaScript plus des déclarations de types, pas du TypeScript brut.
Publication sécurisée de packages npm en 2025
Créer votre compte npm avec 2FA
- Inscrivez-vous sur npmjs.com
- Activez immédiatement l’authentification à deux facteurs (privilégiez WebAuthn/passkeys)
- Tous les nouveaux packages ont désormais l’application 2FA activée par défaut
- Avec le nouveau modèle de connexion basé sur les sessions, la publication de tout package — nouveau ou existant — nécessite 2FA pendant la session
Votre première publication manuelle
npm login crée maintenant un token de session de deux heures. Ces tokens :
- N’apparaissent pas dans l’interface npm
- Expirent automatiquement après deux heures
- Ne peuvent pas être réutilisés en CI/CD
- Imposent toujours 2FA avant publication
Les anciens outils qui s’authentifient via le point de terminaison CouchDB obsolète reçoivent également des tokens de session de deux heures pendant la période de transition.
Pour votre première release :
npm login
npm publish --access public
Le flag --access public est requis pour les packages scopés sur les comptes gratuits.
Vérifiez votre package sur https://www.npmjs.com/package/@yourusername/use-toggle.
Discover how at OpenReplay.com.
npm Trusted Publishing avec CI
Les anciens tutoriels vous disent de créer un NPM_TOKEN et de le stocker comme secret de dépôt. Cette approche est maintenant obsolète : les tokens classiques ont été définitivement révoqués, et les tokens CI à longue durée de vie ne sont plus supportés.
L’alternative moderne est npm Trusted Publishing via GitHub Actions OIDC. GitHub prouve son identité à npm, et npm émet automatiquement des identifiants à courte durée de vie — aucun token stocké requis.
Configurer Trusted Publishing
- Sur npmjs.com, allez dans votre package → Settings → Publishing access
- Ajoutez un nouveau “Trusted Publisher” avec les détails de votre dépôt GitHub
Créer le workflow
Ajoutez .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
Le flag --provenance ajoute une attestation cryptographique liant votre package à son dépôt source — une fonctionnalité de sécurité de la chaîne d’approvisionnement introduite par npm en 2023.
Si OIDC ne peut pas être utilisé (par exemple, runners auto-hébergés), créez un token d’accès granulaire à courte durée de vie en utilisant :
npm token create
Les tokens granulaires peuvent opter pour Bypass 2FA pour la publication CI et doivent expirer dans les 90 jours.
Ce que vous verrez dans les anciens tutoriels
Évitez ces patterns obsolètes :
"main": "index.js"sansexports— utilisezexportspour une résolution ESM appropriée- Cibler Node 10/12/14 — Node 18+ est supporté, mais les nouveaux packages devraient cibler les versions LTS modernes (Node 20 ou 22)
- Packages CommonJS uniquement — ESM est le standard ; livrez en ESM-first
NPM_TOKENpermanent dans chaque workflow — les tokens classiques sont entièrement révoqués ; utilisez Trusted Publishing sans token
Vérifier avant publication
Testez toujours votre package localement avant publication :
npm pack --dry-run
Cela montre exactement quels fichiers seront inclus. Si vous voyez src/ ou node_modules/, votre champ files nécessite un ajustement.
Conclusion
Pour créer et publier un package npm en 2025 : utilisez ESM avec un exports approprié, compilez TypeScript en JavaScript avec déclarations, activez 2FA, et automatisez les releases avec npm Trusted Publishing. Évitez les patterns obsolètes — ils vous causeront des problèmes à vous et à vos utilisateurs.
FAQ
Publiez du JavaScript compilé avec des fichiers de déclaration. Livrez le dossier dist contenant votre JS compilé et les fichiers .d.ts générés. Cela garantit la compatibilité entre différentes versions de TypeScript et outils de build. Du TypeScript brut force les consommateurs à compiler votre code, ce qui peut causer des conflits de version et des builds plus lents.
Utilisez dependencies pour les packages que votre code bundle et livre. Utilisez peerDependencies pour les packages que les consommateurs doivent fournir, comme React pour un hook React. Cela évite les copies dupliquées de grandes bibliothèques dans le bundle final. Votre package attend la version du consommateur plutôt que de bundler la sienne.
Les packages scopés comme @username/package-name sont privés par défaut sur npm. Les comptes npm gratuits ne peuvent pas publier de packages privés, vous devez donc explicitement définir --access public. Ce flag indique à npm de publier le package publiquement. Vous n'en avez besoin que pour la première publication ; les versions ultérieures héritent du niveau d'accès.
Utilisez npm deprecate @scope/package pour avertir les utilisateurs sans supprimer le package. La dépublication complète avec npm unpublish est limitée aux packages publiés dans les 72 heures ou ceux avec un minimum de téléchargements. Pour les packages abandonnés, la dépréciation est préférée car elle avertit les utilisateurs tout en préservant les installations existantes.
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.