jpm

Un gestionnaire de paquets JavaScript rapide, léger et sécurisé par défaut

curl -fsSL https://getjpm.sh | sh

Chaque ligne écrite par Claude Code. Dirigé par un seul ingénieur. Vérifié avec les tests de tous les autres.

  • ~2 MBun seul binaire, aucun runtime à installer
  • 1.22 sinstallation à froid de nuxt sur GitHub CI
  • 34 MBde mémoire pour installer nuxt sur GitHub CI

Vitesse

Rapide là où votre CI passe son temps

Trois vrais projets, quatre phases d'installation, huit gestionnaires de paquets, face au registre npm en direct. Sur GitHub CI, jpm est le plus rapide dans 9 de 12 cas ; les trois autres sont affichés tels que mesurés.

Machine
Phase
Projet

Pas de cache, pas de lockfile, pas de node_modules.

Temps réel d'installation, plus court signifie plus rapideGitHub CI, Linux · nuxt · 591 paquets
GitHub CI, Linux, froid, nuxt · 591 paquets
Gestionnaire de paquetsTemps réel
jpm1.22 s
bun 1.4.21.28 s
pnpm 12.8.11.72 s
aube 2.6.03.00 s
upm 1.3.13.52 s
deno 2.9.67.64 s
yarn 4.18.19.63 s
npm 12.1.018.54 s

Ici, jpm est le plus rapide, 15× plus rapide que npm.

Temps réel, médianes : ubuntu-latest avec 4 cœurs (5 exécutions) et Windows 11 avec Defender activé (3 exécutions), 2026-09-30. Tableaux complets, avec le temps CPU, dans docs/benchmarks.md.

Démarrer

Migrez en une seule commande

Lancez jpm install dans votre projet. jpm importe votre lockfile actuel dans son propre jpm.lock, avec les mêmes versions.

  • package-lock.json et npm-shrinkwrap.json (npm 7+), pnpm-lock.yaml (pnpm 9+) et bun.lock sont repris tels quels : mêmes versions, même arbre, sans aucune requête au registre.
  • yarn.lock, de yarn 1 ou de yarn 2 et suivants, conserve chaque version choisie par yarn. jpm ne demande au registre que ce que yarn.lock n'enregistre pas : peers, plateformes et bins.
  • Votre ancien lockfile reste intact. Supprimez-le quand vous serez prêt.
  • La CI continue de fonctionner pendant la migration : jpm ci et jpm install --frozen-lockfile installent depuis l'ancien lockfile tel quel jusqu'à ce que jpm.lock soit commité.
  • Il lit aussi les workspaces, pnpm-workspace.yaml, les catalogs, les overrides et resolutions, ainsi que les patches.

Anciens formats, lockfiles obsolètes et le reste : docs/migrating.md.

$ cd your-project
$ jpm install   # lit package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock → écrit jpm.lock

Léger

Si léger qu'on oublie sa présence

Un binaire sans rien derrière, une installation qui consomme peu de mémoire et un store qui conserve chaque fichier une seule fois.

Tous les chiffres ne sont pas en faveur de jpm : npm et yarn conservent des tarballs compressés, leurs caches sont donc plus petits. jpm garde ses fichiers décompressés, prêts à être liés.

GitHub CI, Linux, 2026-09-30. Les tailles de binaire sont les chiffres arrondis du README.

Taille du binaire, approximative
Taille du binaire, approximative
jpm~2 MB
pnpm~60 MB
bun~80 MB
aube~150 MB
Pic de mémoire, installation ci de nuxt
Pic de mémoire, installation ci de nuxt
jpm34 MB
bun89 MB
pnpm184 MB
npm387 MB
Disque après une installation à froid de nuxt, node_modules et store
Disque après une installation à froid de nuxt, node_modules et store
jpm244 MB
bun261 MB
pnpm290 MB
npm443 MB
Cache CI après une installation à froid de next
Cache CI après une installation à froid de next
npm194 MB
yarn328 MB
jpm347 MB
pnpm433 MB
bun466 MB

Stockage

Chaque fichier stocké une fois. Chaque paquet construit une fois.

jpm tient un store par machine et construit le répertoire de chaque paquet une seule fois, pour tous les projets qui l'utilisent. Réinstaller revient surtout à créer des liens.

  1. Un store adressé par contenu

    Chaque tarball est vérifié par rapport à son intégrité, puis décompressé une seule fois dans ~/.jpm/store. Chaque fichier est conservé une fois, par son hash, en lecture seule.

  2. Un store virtuel global

    Chaque paquet est construit une fois sous forme d'entrée : name@version, plus une courte empreinte de son graphe de dépendances s'il en a. Ses fichiers sont des liens physiques vers le store, et ses dépendances sont liées à côté de lui, si bien qu'il ne peut importer que ce qu'il a déclaré.

  3. Votre node_modules

    Le node_modules d'un projet pointe vers ces entrées. Une installation à chaud ne crée que ces quelques liens : 4 ms pour nitro sur GitHub CI.

  4. Tous les autres projets

    Le projet suivant sur la machine pointe vers les mêmes entrées. Quand rien n'a changé, une installation répétée vérifie quelques liens et se termine en 1–2 ms.

~/.jpm/storefichiers, par hash3fa19c07e4b271d80b5ec6a3liens physiques~/.jpm/store/v1/linksentrées, construites une fois[email protected]node_modules/debugnode_modules/ms[email protected]node_modules/msapp-one/app-two/node_modules/debugnode_modules/debugliens

Next.js et Nuxt : dans le projet

Turbopack, côté Next, ne compile rien en dehors du projet, et Nuxt importe des paquets qu'il ne déclare pas. Pour un projet qui dépend de next ou de nuxt, jpm construit donc les entrées dans node_modules/.jpm, toujours en liens physiques depuis le store.

node_modules/next -> .jpm/[email protected]…/node_modules/next
node_modules/.jpm/[email protected]…/node_modules/next/
node_modules/.jpm/[email protected]/node_modules/react/

Le tableau complet : docs/how-it-works.md.

Sécurité

Sécurisé par défaut

Le réglage sûr est celui que vous obtenez sans rien demander. L'assouplir est votre décision, prise dans vos propres paramètres, pas dans ceux d'un paquet ou d'un dépôt cloné.

  • Les scripts d'installation vous attendent

    Les scripts d'installation d'une dépendance, par lesquels passe la plupart des malwares npm, ne s'exécutent pas tant que vous n'avez pas approuvé ce paquet et cette version avec jpm approve. Une nouvelle version attend à nouveau votre approbation.

  • Les nouvelles versions attendent un jour

    Une version publiée dans la dernière journée n'est pas retenue (min-release-age), même quand un paquet enfoui dans l'arbre l'épingle exactement : une release détournée ne peut pas s'infiltrer par une version épinglée.

  • Pas de sources surprises

    Un paquet publié ne peut pas tirer de dépendances git ou tarball, ni de chemins en dehors de lui-même. Seuls votre projet et ses workspaces décident d'où vient le code.

  • Vérifié avant d'être visible

    Chaque paquet est vérifié par rapport à l'intégrité inscrite dans le lockfile avant qu'aucun de ses fichiers ne soit visible par votre projet.

  • Aucun secret dans le lockfile

    Les identifiants n'atterrissent jamais dans jpm.lock : les tokens restent dans votre .npmrc, et une URL git contenant un mot de passe est refusée.

  • Un dépôt cloné ne peut pas baisser la garde

    Le .npmrc propre à un projet ne peut pas désactiver les vérifications TLS, changer de CA ou de proxy, ni réduire l'ancienneté minimale des versions. jpm ignore ces réglages à cet endroit et les signale dans un avertissement.

  • Son propre TLS, sans OpenSSL

    jpm parle TLS avec son propre code, testé avec Project Wycheproof et les vecteurs des RFC, et vérifie les certificats avec les racines de Mozilla et celles de votre système.

  • Runtimes vérifiés par signature

    Un runtime Node.js demandé par un paquet est vérifié par rapport au SHASUMS256.txt de la release, et n'est considéré comme fiable qu'une fois sa signature validée par les clés de release de Node.

  • Moins de surface d'attaque

    Un seul binaire de ~2 MB, sans runtime ni arbre de dépendances à installer : moins de code entre vous et le registre.

Sécurisé par défaut ne veut pas dire sandbox : un script que vous approuvez s'exécute avec vos droits. Les détails : docs/install-scripts.md et docs/configuration.md.

L'histoire

Écrit par Claude Code. Vérifié avec les tests de tous les autres.

Tout a commencé avec un épisode du podcast Syntax qui présentait upm comme plus rapide et plus léger que les autres. Léger, parce qu'il s'appuie sur Node.js. D'où la question : et s'il était porté en Rust et vraiment léger ? Et que faudrait-il pour transformer le premier jet d'une IA en quelque chose à qui l'on confierait sa CI ?

Claude Code, avec Claude Opus 5.5, a écrit chaque ligne, y compris son propre TLS et sa cryptographie. JT Turner, ingénieur depuis 27 ans, a pris les décisions. Quand Claude a émis des réserves sur l'idée d'écrire notre propre TLS, la condition a été : le tester comme si on ne lui faisait pas confiance. Chaque « ça marche » est donc vérifié avec les tests de quelqu'un d'autre : Wycheproof, les RFC et les suites de npm, pnpm, yarn et bun.

Les chiffres tranchent. Un client HTTP/2 a été construit, mesuré sur les runners de GitHub et sur un poste de bureau, s'est révélé plus lent et plus gourmand en CPU, puis a été supprimé.

jpm est-il parfait ? Non. La perfection n'existe pas. Il y a le suffisant, il y a l'excellent, et il y a le suffisamment testé pour savoir lequel des deux on a.

JT Turner

Lire toute l'histoire

Essayez jpm dans votre CI. Puis allez construire ce projet pour lequel vous pensiez ne pas avoir le temps.

Installer jpm