jpm

Ein schneller, kleiner, standardmäßig sicherer Paketmanager für JavaScript

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

Jede Zeile von Claude Code geschrieben. Gesteuert von einem einzigen Engineer. Geprüft mit den Tests aller anderen.

  • ~2 MBeine Binärdatei, keine Runtime nötig
  • 1.22 skalte nuxt-Installation auf GitHub CI
  • 34 MBArbeitsspeicher für die nuxt-Installation auf GitHub CI

Tempo

Schnell da, wo deine CI ihre Zeit verbringt

Drei echte Projekte, vier Installationsphasen, acht Paketmanager, gegen die echte npm-Registry. Auf GitHub CI ist jpm in 9 von 12 Feldern am schnellsten; die anderen drei zeigen wir so, wie sie gemessen wurden.

Rechner
Phase
Projekt

Kein Cache, kein Lockfile, kein node_modules.

Installationsdauer (Wall-Time), kürzer ist schnellerGitHub CI, Linux · nuxt · 591 Pakete
GitHub CI, Linux, kalt, nuxt · 591 Pakete
PaketmanagerWall-Time
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

Hier ist jpm am schnellsten, 15× schneller als npm.

Wall-Time, Mediane: ubuntu-latest mit 4 Kernen (5 Läufe) und Windows 11 mit aktivem Defender (3 Läufe), 2026-09-30. Vollständige Tabellen inklusive CPU-Zeit unter docs/benchmarks.md.

Loslegen

Umstieg mit einem Befehl

Führ jpm install in deinem Projekt aus. jpm übernimmt dein vorhandenes Lockfile in ein eigenes jpm.lock, mit denselben Versionen.

  • package-lock.json und npm-shrinkwrap.json (npm 7+), pnpm-lock.yaml (pnpm 9+) und bun.lock werden unverändert übernommen: dieselben Versionen, derselbe Baum, keine Registry-Abfragen.
  • yarn.lock aus yarn 1 oder yarn 2 und neuer behält jede Version, die yarn gewählt hat. jpm fragt die Registry nur nach dem, was yarn.lock nicht festhält: Peers, Plattformen und Bins.
  • Dein altes Lockfile bleibt unangetastet. Lösch es, wenn du so weit bist.
  • CI läuft während des Umstiegs weiter: jpm ci und jpm install --frozen-lockfile installieren aus dem alten Lockfile, so wie es ist, bis jpm.lock committet ist.
  • Außerdem liest jpm Workspaces, pnpm-workspace.yaml, Catalogs, Overrides und Resolutions sowie Patches.

Ältere Formate, veraltete Lockfiles und alles Weitere: docs/migrating.md.

$ cd your-project
$ jpm install   # liest package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock → schreibt jpm.lock

Schlank

So klein, dass du vergisst, dass es da ist

Eine Binärdatei, hinter der nichts weiter hängt, eine Installation, die wenig Speicher braucht, und ein Store, der jede Datei nur einmal ablegt.

Nicht jede Zahl spricht für jpm: npm und yarn behalten komprimierte Tarballs, daher sind ihre Caches kleiner. jpm hält seine Dateien entpackt, bereit zum Verlinken.

GitHub CI, Linux, 2026-09-30. Die Binärgrößen sind die gerundeten Werte aus der README.

Größe der Binärdatei, ungefähr
Größe der Binärdatei, ungefähr
jpm~2 MB
pnpm~60 MB
bun~80 MB
aube~150 MB
Maximaler Speicherverbrauch, nuxt-Installation (ci)
Maximaler Speicherverbrauch, nuxt-Installation (ci)
jpm34 MB
bun89 MB
pnpm184 MB
npm387 MB
Speicherplatz nach kalter nuxt-Installation, node_modules und Store
Speicherplatz nach kalter nuxt-Installation, node_modules und Store
jpm244 MB
bun261 MB
pnpm290 MB
npm443 MB
CI-Cache nach kalter next-Installation
CI-Cache nach kalter next-Installation
npm194 MB
yarn328 MB
jpm347 MB
pnpm433 MB
bun466 MB

Speicher

Jede Datei einmal gespeichert. Jedes Paket einmal gebaut.

jpm führt einen Store pro Rechner und baut das Verzeichnis jedes Pakets einmal, für alle Projekte, die es nutzen. Eine erneute Installation besteht fast nur aus dem Anlegen von Links.

  1. Ein inhaltsadressierter Store

    Jeder Tarball wird gegen seine Integrity geprüft und dann einmal nach ~/.jpm/store entpackt. Jede Datei liegt dort genau einmal, nach ihrem Hash, schreibgeschützt.

  2. Ein globaler virtueller Store

    Jedes Paket wird einmal als Eintrag gebaut: name@version, plus ein kurzer Digest seines Abhängigkeitsgraphen, falls es Abhängigkeiten hat. Seine Dateien sind Hardlinks aus dem Store, und seine Abhängigkeiten werden direkt daneben verlinkt, sodass es nur importieren kann, was es deklariert hat.

  3. Dein node_modules

    Das node_modules eines Projekts verlinkt auf diese Einträge. Eine warme Installation legt nur diese paar Links an: 4 ms für nitro auf GitHub CI.

  4. Jedes weitere Projekt

    Das nächste Projekt auf dem Rechner verlinkt auf dieselben Einträge. Hat sich nichts geändert, prüft eine erneute Installation ein paar Links und ist in 1–2 ms fertig.

~/.jpm/storeDateien, nach Hash3fa19c07e4b271d80b5ec6a3Hardlinks~/.jpm/store/v1/linksEinträge, einmal gebautdebug@4.4.3-q7Lr2KaXnode_modules/debugnode_modules/msms@2.1.3node_modules/msapp-one/app-two/node_modules/debugnode_modules/debugLinks

Next.js und Nuxt: im Projekt

Turbopack von Next kompiliert nichts außerhalb des Projekts, und Nuxt importiert Pakete, die es nicht deklariert. Für ein Projekt, das von next oder nuxt abhängt, baut jpm die Einträge stattdessen in node_modules/.jpm, weiterhin per Hardlink aus dem Store.

node_modules/next -> .jpm/next@16.0.0-…/node_modules/next
node_modules/.jpm/next@16.0.0-…/node_modules/next/
node_modules/.jpm/react@19.2.0/node_modules/react/

Das ganze Bild: docs/how-it-works.md.

Sicherheit

Standardmäßig sicher

Die sichere Einstellung bekommst du, ohne danach zu fragen. Sie zu lockern ist deine Entscheidung, getroffen in deinen eigenen Einstellungen, nicht in denen eines Pakets oder eines geklonten Repositorys.

  • Install-Skripte warten auf dich

    Die Install-Skripte einer Abhängigkeit, über die die meiste npm-Malware läuft, starten erst, wenn du dieses Paket in dieser Version mit jpm approve freigibst. Eine neue Version muss erneut freigegeben werden.

  • Neue Versionen warten einen Tag

    Eine Version, die vor weniger als einem Tag veröffentlicht wurde, wird nicht gewählt (min-release-age), selbst wenn ein Paket tief im Baum sie exakt pinnt. So kann ein gekapertes Release nicht über einen Pin hereinrutschen.

  • Keine unerwarteten Quellen

    Ein veröffentlichtes Paket kann weder Git- oder Tarball-Abhängigkeiten nachziehen noch Pfade außerhalb seiner selbst. Nur dein Projekt und seine Workspaces bestimmen, woher Code kommt.

  • Geprüft, bevor es sichtbar wird

    Jedes Paket wird gegen die Integrity im Lockfile geprüft, bevor auch nur eine seiner Dateien für dein Projekt sichtbar ist.

  • Keine Geheimnisse im Lockfile

    Zugangsdaten landen nie in jpm.lock: Tokens bleiben in deiner .npmrc, und eine Git-URL mit Passwort wird abgelehnt.

  • Ein geklontes Repo kann die Latte nicht senken

    Die eigene .npmrc eines Projekts kann weder TLS-Prüfungen abschalten noch CA oder Proxy austauschen noch das Release-Alter lockern. jpm ignoriert solche Einstellungen dort und nennt sie in einer Warnung.

  • Eigenes TLS, kein OpenSSL

    jpm spricht TLS mit eigenem Code, getestet gegen Project Wycheproof und die Testvektoren der RFCs, und prüft Zertifikate gegen die Root-Zertifikate von Mozilla und die deines Systems.

  • Runtimes per Signatur geprüft

    Eine Node.js-Runtime, die ein Paket anfordert, wird gegen die SHASUMS256.txt des Releases geprüft, und dieser Datei wird erst vertraut, wenn ihre Signatur zu den Release-Schlüsseln von Node passt.

  • Weniger Angriffsfläche

    Eine ~2 MB große Binärdatei, ohne Runtime und ohne eigenen Abhängigkeitsbaum, der installiert werden muss: weniger Code zwischen dir und der Registry.

Standardmäßig sicher heißt nicht Sandbox: Ein Skript, das du freigibst, läuft mit deinen Rechten. Details: docs/install-scripts.md und docs/configuration.md.

Die Geschichte

Geschrieben von Claude Code. Geprüft mit den Tests aller anderen.

Angefangen hat es mit einer Folge des Syntax-Podcasts, in der upm als schneller und kleiner als der Rest gelobt wurde. Klein, weil es auf Node.js aufsetzt. Also: Was, wenn man es nach Rust portiert und wirklich klein macht? Und was braucht es, damit aus dem One-Shot einer KI etwas wird, dem man in CI vertraut?

Claude Code mit Claude Opus 5.5 hat jede Zeile geschrieben, eigenes TLS und eigene Kryptografie inklusive. JT Turner, Engineer seit 27 Jahren, hat die Entscheidungen getroffen. Als Claude sich gegen ein eigenes TLS sträubte, lautete die Bedingung: Teste es, als würden wir ihm nicht trauen. Deshalb wird jedes „es funktioniert“ gegen fremde Tests geprüft: Wycheproof, die RFCs und die Testsuiten von npm, pnpm, yarn und bun.

Die Zahlen entscheiden. Ein HTTP/2-Client wurde gebaut, auf GitHubs Runnern und einem Desktop-Rechner gebenchmarkt, als langsamer und CPU-hungriger befunden und wieder gelöscht.

Ist jpm perfekt? Nein. Perfekt gibt es nicht. Es gibt gut genug, es gibt großartig, und es gibt genug getestet, um zu wissen, was davon man hat.

JT Turner

Die ganze Geschichte lesen

Probier jpm in deiner CI aus. Und dann bau das Ding, für das du nie Zeit zu haben glaubtest.

jpm installieren