pnpm vs bun install Comparaison

Store adressable par contenu, isolation stricte, audit de chaîne d'approvisionnement mature

VS
bun install

Composant d'installation du runtime Bun, au cœur Rust, rapide et tout-en-un

16 min de lectureOutils

Verdict rapide

Il n'y a pas de gagnant absolu ; les deux outils optimisent des priorités différentes. Choisis pnpm si tu veux rester indépendant du runtime et auditer la politique à chaque commande modifiant le lockfile. bun install est séduisant si tu utilises déjà Bun comme runtime et que le gain disque/vitesse du global virtual store est critique. Les deux bloquent postinstall par défaut ; la différence se situe dans l'emplacement des points de contrôle. Ne mélange pas les deux dans le même dépôt — un seul lockfile, une seule source de vérité.

pnpmbun install
Lire le verdict complet

Comparaison des scores

Chargement du graphique...

Notation détaillée

Notation détaillée: pnpm et bun install — notes sur 10, catégorie par catégorie
Catégoriepnpmbun install
Performance
8/10
9/10
Facilité d'apprentissage
7/10
8/10
Écosystème
9/10
6/10
Communauté
8/10
7/10
Marché de l'emploi
7/10
6/10
Pérennité
8/10
8/10

Avantages & Inconvénients

pnpm

Avantages

  • Grâce au store adressable par contenu, chaque version de paquet n'est conservée qu'en un seul exemplaire sur le disque, ce qui réduit l'utilisation du disque
  • La structure stricte de node_modules bloque les phantom dependencies par défaut, sans configuration supplémentaire
  • Depuis les versions 12.2-12.3, --trust-lockfile/--trust-policy peuvent désormais être imposés aussi sur les commandes remove et update
  • Grâce à la allowlist allowBuilds, les scripts postinstall dépendent d'une liste explicite et auditable (onlyBuiltDependencies dans pnpm 10, allowBuilds depuis la v11)
  • Une intégration workspace mûrie au fil des années avec Turborepo, Nx et Changesets
  • Fonctionnant sur Node.js, il reste indépendant du choix de runtime et n'enferme pas le projet dans un seul outil
  • Le champ catalog: centralise la gestion des versions de dépendances communes dans tout le monorepo
  • Depuis la 12.x, le cœur a été réécrit en Rust ; la découverte du workspace et l'analyse du lockfile s'exécutent en parallèle

Inconvénients

  • La structure node_modules basée sur des symlinks peut créer des incompatibilités avec certains outils Node anciens/naïfs (qui attendent une résolution non stricte)
  • Remplir manuellement la allowlist allowBuilds représente une étape supplémentaire à chaque ajout d'un paquet nécessitant un native-build
  • Les mesures de vitesse publiées par Bun sont faites entre ses propres linkers ; pour situer pnpm à cette échelle, il faut mesurer dans son propre dépôt
  • Pas de runtime propre — il n'offre pas une expérience intégrée installation + exécution + test issue d'un seul outil
  • Intégrer correctement le store dans la stratégie de cache CI (pnpm store path) nécessite une étape de configuration manuelle

Idéal pour

Les équipes en production sur Node.js qui veulent rester indépendantes du runtimeLes grands monorepos orchestrés avec Turborepo ou NxLes projets réglementés qui veulent auditer la politique de chaîne d'approvisionnement à chaque commande modifiant le lockfileLes runners CI à espace disque limité ou les organisations ayant de nombreux projets similairesLes équipes cherchant une migration progressive et à faible risque depuis des projets npm/Yarn existants

bun install

Avantages

  • Avec Bun 1.4, le global virtual store opt-in accélère nettement les installations en mode --linker=isolated
  • Les scripts postinstall sont bloqués par défaut ; la allowlist trustedDependencies audite explicitement la chaîne d'approvisionnement
  • Les scénarios d'installation CI/air-gapped peuvent être exprimés clairement avec les flags --offline et --prefer-offline
  • Le mode isolated installs bloque architecturalement les phantom dependencies, avec une approche proche de celle de pnpm
  • Le format de lockfile texte bun.lock (par défaut depuis v1.2+) produit un diff lisible en revue de PR
  • L'installation, le runtime et le test runner venant d'un seul outil, il offre une expérience intégrée sur les projets Bun greenfield
  • Le filtrage d'installation par workspace via bun install --filter est pris en charge nativement

Inconvénients

  • Le global virtual store est désactivé par défaut et ne fonctionne qu'avec le linker isolated ; il faut l'activer explicitement dans bunfig.toml pour en voir le gain
  • Le linker isolated n'est par défaut que sur les nouveaux projets workspace/monorepo (configVersion = 1) ; sur les projets mono-paquet et les projets existants antérieurs à v1.3.2, le défaut reste hoisted, donc le risque de phantom dependency doit être fermé manuellement
  • L'intégration avec des outils comme Turborepo/Nx a un historique de maturation plus court que celui de pnpm
  • La allowlist par défaut intégrée trustedDependencies de Bun ne couvre que les paquets issus de npm ; les dépendances file:/link:/git:/github: doivent être ajoutées manuellement
  • L'outil d'installation faisant partie du runtime Bun, il crée une dépendance à l'outil pour les équipes voulant migrer vers un autre runtime JS
  • La migration de l'ancien format binaire bun.lockb vers le nouveau bun.lock texte nécessite une étape de migration supplémentaire sur les projets existants

Idéal pour

Les équipes utilisant déjà le runtime Bun en productionLes projets greenfield où la vitesse d'installation et le contrôle du cache CI sont critiquesLes équipes voulant un contrôle clair par flags dans des environnements CI offline/air-gappedLes projets Bun-only de petite à moyenne taille attendant installation + exécution + test d'un seul outil

Comparaison de code

pnpm
// pnpm 12.3 — installation contrôlée avec allowBuilds et filtrage de workspace
// package.json (racine)
{
  "name": "monorepo-root",
  "private": true,
  "packageManager": "[email protected]"
}

// pnpm-workspace.yaml — allowBuilds est arrivé en v10.26.0 ; la v11 a supprimé les anciens noms (onlyBuiltDependencies, etc.)
packages:
  - "apps/*"
  - "packages/*"

allowBuilds:
  esbuild: true
  sharp: true
  core-js: false

catalog:
  react: ^19.2.3
  typescript: ^5.7.0

// Étape d'installation CI (GitHub Actions)
- name: Install dependencies
  run: pnpm install --frozen-lockfile --trust-policy=no-downgrade

// Lors de la suppression d'un paquet, tout le lockfile est revalidé face aux politiques actives
pnpm remove left-pad --filter ./apps/web --trust-lockfile

// Installation uniquement pour les paquets workspace modifiés
pnpm install --filter "...[origin/main]"

// Ajouter l'emplacement du store à la clé de cache CI
pnpm store path
bun install
// Bun 1.4 — isolated installs + global virtual store + installation offline
// bunfig.toml (racine)
[install]
linker = "isolated"
globalStore = true
exact = false

// package.json
{
  "name": "monorepo-root",
  "private": true,
  "workspaces": ["apps/*", "packages/*"],
  "trustedDependencies": [
    "esbuild",
    "sharp",
    "@prisma/client"
  ]
}

// Étape d'installation CI (GitHub Actions) — verrouillée et compatible offline
- name: Install dependencies
  run: bun install --frozen-lockfile --prefer-offline

// Voir les scripts postinstall bloqués
bun pm untrusted

// Marquer un paquet comme fiable
bun pm trust sharp

// Installation pour des paquets workspace spécifiques
bun install --filter "./apps/web"

// Installation entièrement offline (aucun accès réseau)
bun install --offline

Conclusion

Il n'y a pas de gagnant absolu ; les deux outils optimisent des priorités différentes. Choisis pnpm si tu veux rester indépendant du runtime et auditer la politique à chaque commande modifiant le lockfile. bun install est séduisant si tu utilises déjà Bun comme runtime et que le gain disque/vitesse du global virtual store est critique. Les deux bloquent postinstall par défaut ; la différence se situe dans l'emplacement des points de contrôle. Ne mélange pas les deux dans le même dépôt — un seul lockfile, une seule source de vérité.

Obtenir une consultation gratuite
FAQ

Questions fréquentes

Cela dépend du scénario. La mesure publiée par Bun compare ses propres linkers entre eux : sur une fixture React/webpack/Babel/jest de 1 400 paquets, l'installation à chaud est de 823,9 ms avec le linker hoisted contre 124,8 ms avec le linker isolated + global store (Apple Silicon macOS, hyperfine). Le store adressable par contenu de pnpm repose lui aussi sur une lecture disque pour les installations à chaud, donc les deux sont rapides dans les bonnes conditions. Il faut mesurer la différence entre les deux outils sur la taille de ton propre dépôt et ta stratégie de cache CI — ne transpose pas le résultat d'une seule fixture à ton monorepo.

Articles de blog associés

Voir tous les articles

Projets associés

Voir tous les projets
Toutes les comparaisons