jpm

Um gerenciador de pacotes para JavaScript rápido, pequeno e seguro por padrão

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

Cada linha escrita pelo Claude Code. Dirigido por um único engenheiro. Conferido com os testes de todos os outros.

  • ~2 MBum binário, sem runtime para instalar
  • 1.22 sinstalação a frio do nuxt no GitHub CI
  • 34 MBde memória para instalar o nuxt no GitHub CI

Velocidade

Rápido onde o seu CI gasta tempo

Três projetos reais, quatro fases de instalação, oito gerenciadores de pacotes, contra o registro do npm ao vivo. No GitHub CI, o jpm é o mais rápido em 9 de 12 casos; os outros três aparecem exatamente como foram medidos.

Máquina
Fase
Projeto

Sem cache, sem lockfile, sem node_modules.

Tempo real de instalação; menor é mais rápidoGitHub CI, Linux · nuxt · 591 pacotes
GitHub CI, Linux, fria, nuxt · 591 pacotes
Gerenciador de pacotesTempo real
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

Aqui o jpm é o mais rápido, 15× mais rápido que o npm.

Tempo real, medianas: ubuntu-latest com 4 núcleos (5 execuções) e Windows 11 com o Defender ativado (3 execuções), 2026-09-30. Tabelas completas, com tempo de CPU, em docs/benchmarks.md.

Começar

Troque com um só comando

Rode jpm install no seu projeto. O jpm importa o lockfile que você já tem para o próprio jpm.lock, com as mesmas versões.

  • package-lock.json e npm-shrinkwrap.json (npm 7+), pnpm-lock.yaml (pnpm 9+) e bun.lock são aproveitados como estão: as mesmas versões e a mesma árvore, sem consultas ao registro.
  • O yarn.lock, do yarn 1 ou do yarn 2 em diante, mantém todas as versões que o yarn escolheu. O jpm só consulta o registro para o que o yarn.lock não registra: peers, plataformas e bins.
  • Seu lockfile antigo fica intacto. Apague quando estiver pronto.
  • O CI continua funcionando durante a troca: jpm ci e jpm install --frozen-lockfile instalam a partir do lockfile antigo como ele está até o jpm.lock ser commitado.
  • Ele também lê workspaces, pnpm-workspace.yaml, catalogs, overrides e resolutions, e patches.

Formatos antigos, lockfiles desatualizados e o resto: docs/migrating.md.

$ cd your-project
$ jpm install   # lê package-lock.json / pnpm-lock.yaml / yarn.lock / bun.lock → grava jpm.lock

Enxuto

Pequeno a ponto de você esquecer que ele está ali

Um binário sem nada por trás, uma instalação que usa pouca memória e um store que guarda cada arquivo uma única vez.

Nem todo número favorece o jpm: o npm e o yarn guardam tarballs compactados, então os caches deles são menores. O jpm guarda seus arquivos descompactados, prontos para linkar.

GitHub CI, Linux, 2026-09-30. Os tamanhos dos binários são os valores arredondados do README.

Tamanho do binário, aproximado
Tamanho do binário, aproximado
jpm~2 MB
pnpm~60 MB
bun~80 MB
aube~150 MB
Pico de memória, instalação ci do nuxt
Pico de memória, instalação ci do nuxt
jpm34 MB
bun89 MB
pnpm184 MB
npm387 MB
Disco após uma instalação a frio do nuxt, node_modules e store
Disco após uma instalação a frio do nuxt, node_modules e store
jpm244 MB
bun261 MB
pnpm290 MB
npm443 MB
Cache do CI após uma instalação a frio do next
Cache do CI após uma instalação a frio do next
npm194 MB
yarn328 MB
jpm347 MB
pnpm433 MB
bun466 MB

Armazenamento

Cada arquivo guardado uma vez. Cada pacote montado uma vez.

O jpm mantém um store por máquina e monta o diretório de cada pacote uma única vez, para todos os projetos que o usam. Instalar de novo é basicamente criar links.

  1. Um store endereçado por conteúdo

    Cada tarball é conferido com a sua integridade e descompactado uma única vez em ~/.jpm/store. Cada arquivo é guardado uma vez, pelo hash, somente leitura.

  2. Um store virtual global

    Cada pacote é montado uma vez como uma entrada: name@version, mais um digest curto do seu grafo de dependências quando ele tem dependências. Os arquivos dele são hardlinks do store, e as dependências são linkadas ao lado, então ele só consegue importar o que declarou.

  3. O seu node_modules

    O node_modules de um projeto aponta para essas entradas. Uma instalação a quente cria só esses poucos links: 4 ms para o nitro no GitHub CI.

  4. Todos os outros projetos

    O próximo projeto na máquina aponta para as mesmas entradas. Quando nada mudou, uma instalação repetida confere alguns links e termina em 1–2 ms.

~/.jpm/storearquivos, por hash3fa19c07e4b271d80b5ec6a3hardlinks~/.jpm/store/v1/linksentradas, montadas uma vez[email protected]node_modules/debugnode_modules/ms[email protected]node_modules/msapp-one/app-two/node_modules/debugnode_modules/debuglinks

Next.js e Nuxt: dentro do projeto

O Turbopack do Next não compila nada fora do projeto, e o Nuxt importa pacotes que não declara. Para um projeto que depende de next ou nuxt, o jpm monta as entradas em node_modules/.jpm, ainda com hardlinks do 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/

O quadro completo: docs/how-it-works.md.

Segurança

Seguro por padrão

A configuração segura é a que você recebe sem pedir. Afrouxar alguma é decisão sua, tomada nas suas próprias configurações, e não nas de um pacote ou de um repositório clonado.

  • Scripts de instalação esperam por você

    Os scripts de instalação de uma dependência, o caminho pelo qual roda a maior parte do malware do npm, só rodam depois que você aprova aquele pacote e versão com jpm approve. Uma versão nova volta a esperar aprovação.

  • Versões novas esperam um dia

    Uma versão publicada no último dia não é escolhida (min-release-age), mesmo quando um pacote lá no fundo da árvore a fixa exatamente, então um release sequestrado não entra de carona numa versão fixada.

  • Nada de origens inesperadas

    Um pacote publicado não pode puxar dependências de git ou de tarball, nem caminhos fora dele mesmo. Só o seu projeto e os workspaces dele decidem de onde o código vem.

  • Conferido antes de ficar visível

    Cada pacote é conferido com a integridade registrada no lockfile antes que qualquer arquivo dele fique visível para o seu projeto.

  • Nenhum segredo no lockfile

    Credenciais nunca vão parar no jpm.lock: os tokens ficam no seu .npmrc, e uma URL de git com senha é recusada.

  • Um repo clonado não baixa o nível

    O .npmrc do próprio projeto não pode desligar as verificações de TLS, trocar a CA ou o proxy, nem afrouxar a idade mínima das versões. O jpm ignora essas opções ali e as lista num aviso.

  • TLS próprio, sem OpenSSL

    O jpm fala TLS com código próprio, testado com o Project Wycheproof e os vetores das RFCs, e valida certificados com as raízes da Mozilla e as do seu sistema.

  • Runtimes verificados por assinatura

    Um runtime de Node.js pedido por um pacote é conferido com o SHASUMS256.txt do release, e só é confiável quando a assinatura bate com as chaves de release do Node.

  • Menos para atacar

    Um único binário de ~2 MB, sem runtime e sem árvore de dependências própria para instalar: menos código entre você e o registro.

Seguro por padrão não é uma sandbox: um script que você aprova roda com as suas permissões. Os detalhes: docs/install-scripts.md e docs/configuration.md.

A história

Escrito pelo Claude Code. Conferido com os testes de todos os outros.

Começou com um episódio do podcast Syntax que apresentava o upm como mais rápido e menor que os demais. Pequeno, porque roda em Node.js. Então: e se ele fosse portado para Rust e ficasse pequeno de verdade? E o que seria preciso para transformar a primeira tentativa de uma IA em algo em que você confiaria no CI?

O Claude Code, rodando o Claude Opus 5.5, escreveu cada linha, incluindo o próprio TLS e a criptografia. JT Turner, engenheiro há 27 anos, tomou as decisões. Quando o Claude questionou a ideia de escrevermos nosso próprio TLS, a condição foi: testar como se não confiássemos nele. Por isso cada "funciona" é conferido com os testes de outras pessoas: Wycheproof, as RFCs e as suítes do npm, pnpm, yarn e bun.

Os números decidem. Um cliente HTTP/2 foi construído, medido nos runners do GitHub e num desktop, se mostrou mais lento e mais faminto por CPU, e foi apagado.

O jpm é perfeito? Não. Perfeito não existe. Existe o bom o bastante, existe o ótimo, e existe o testado o bastante para saber qual dos dois você tem.

JT Turner

Leia a história completa

Experimente o jpm no seu CI. Depois vá construir aquilo para o que você achava que não tinha tempo.

Instalar o jpm