Per què he canviat de Bun a Deno per a les Skills de Claude Code
La característica d'autoinstal·lació de Bun es trenca quan existeix qualsevol
directori node_modules en rutes pares. Això fa que Bun no sigui fiable per a
skills portables de Claude Code que s'executen des de directoris de projecte o
monorepos. Després de provar
el meu enfocament anterior amb npx bun
en entorns reals, vaig canviar a Deno. Aquí explico per què l'especificador
npm: de Deno és la millor opció per a skills TypeScript autocontinguts.
L'autoinstal·lació de Bun només funciona quan no existeix un directori
node_modules en el directori de treball o en qualsevol directori pare. Quan
node_modules està present en qualsevol lloc superior de l'arbre, Bun canvia a
la resolució de mòduls estàndard de Node.js. Els especificadors de versió en les
importacions—la característica principal que feia útil l'enfocament—llancen
errors VersionSpecifierNotAllowedHere:
$ cd ~/my-project # té node_modules/$ cat skill.ts#!/usr/bin/env -S npx -y bunimport chalk from "chalk@^5.0.0"console.log(chalk.green("Hello"))$ ./skill.tserror: VersionSpecifierNotAllowedHereimport chalk from "chalk@^5.0.0"^
Això es trenca en escenaris pràctics. Executar una skill des de dins d'un
directori de projecte? Trencat. Treballar en un monorepo on algun avantpassat té
node_modules? Trencat. El teu directori home casualment té un node_modules
antic d'un experiment oblidat? Trencat.
Per a skills de Claude Code portables que podrien executar-se des de qualsevol
lloc, això és una trampa. L'script funciona quan el proves a
~/.claude/skills/, després falla misteriosament quan Claude l'invoca des d'un
directori diferent. El missatge d'error enfosqueix el problema—diagnosticar-lo
requereix entendre la lògica de resolució interna de Bun.
El crèdit per la solució és per a J Edward Wynia, qui em va assenyalar cap a Deno en resposta a aquell article. Vaig oblidar per què em vaig saltar Deno inicialment—probablement perquè la sintaxi de Bun semblava més neta—però el suggeriment era correcte.
Per què Deno Resol Això
L'especificador npm: de Deno funciona independentment de si existeix
node_modules. Les dependències sempre van a la memòria cau global de Deno a
~/.cache/deno. Els directoris node_modules locals no afecten la
resolució—encara que necessites la flag --node-modules-dir=false per assegurar
aquest comportament quan executes des de directoris que ja tenen una carpeta
node_modules. Comportament consistent a tot arreu.
El mateix truc de distribució amb npx funciona. Igual que npx -y bun, pots
utilitzar npx -y deno per executar Deno sense instal·lar-lo globalment.
Qualsevol entorn amb npm pot executar scripts de Deno.
Una advertència: si Deno ja està instal·lat al teu sistema, npx -y deno encara
descarrega una còpia separada a la memòria cau de npm (~40MB, comparable al cost
de primera descàrrega de ~100MB de Bun). Per a sistemes amb Deno preinstal·lat,
utilitza deno run directament. L'enfocament npx apunta a la
portabilitat—scripts que funcionen en qualsevol màquina amb npm, independentment
del que estigui preinstal·lat.
L'Enfocament Deno
Així és com es veu una skill basada en Deno:
#!/usr/bin/env -S npx -y deno run --node-modules-dir=false --allow-read --allow-writeimport { parse } from "npm:csv-parse@^5.0/sync";import chalk from "npm:chalk@^5.0.0";import { z } from "npm:zod@^3.23";const inputPath = Deno.args[0];const content = await Deno.readTextFile(inputPath);const rows = parse(content, { columns: true });console.log(chalk.green(`Parsed ${rows.length} rows`));
El prefix npm: és més verbós que les importacions directes de Bun, però
clarifica l'origen dels paquets. TypeScript funciona nativament. La fixació de
versions viu a la ruta d'importació, igual que amb Bun. No es requereix
deno.json ni mapa d'importació—les dependències es resolen directament des
dels especificadors.
Deno requereix banderes de permisos—--allow-read, --allow-write,
--allow-net, etc. Més verbós que Bun, però declares exactament el que fa
l'script. Per a skills que s'executen a través de Claude Code, els permisos
explícits documenten a què pot accedir l'script. Per a entorns de confiança,
--allow-all (o -A) se salta la cerimònia.
Compromisos
| Aspecte | Bun | Deno |
|---|---|---|
| Sintaxi d'importació | import x from "[email protected]" | import x from "npm:[email protected]" |
| Segur amb node_modules | No | Sí |
| Rendiment brut | ~20-30% més ràpid | Lleugerament més lent |
| TypeScript | Natiu | Natiu |
| Model de permisos | Permissiu per defecte | Requereix banderes explícites |
Bun és més ràpid. Temps d'inici, rendiment en execució, servei HTTP—Bun supera consistentment Deno als benchmarks. Si estàs construint una API de producció o una eina CLI crítica per al rendiment, això importa.
Per a les skills de Claude Code, no importa.
Per Què el Rendiment No Importa Aquí
El temps de pensament de l'agent empetiteix el temps d'execució de l'script. Claude triga de dos a cinc segons a decidir què fer a continuació. Una skill que s'executa en 50 mil·lisegons enfront de 80 mil·lisegons és efectivament el mateix—ambdós són instantanis comparats amb el bucle de decisió de l'agent.
La fiabilitat importa més. Una skill que funciona des de qualsevol directori és més valuosa que una skill que és un 30% més ràpida però es trenca en monorepos.
Exemple Pràctic per a Skills
L'estructura segueix el mateix patró de
l'article original—un
SKILL.md apuntant a scripts executables. Els únics canvis són el shebang i les
APIs específiques de Deno:
#!/usr/bin/env -S npx -y deno run --node-modules-dir=false --allow-read --allow-writeimport { parse } from "npm:csv-parse@^5.0/sync";import * as XLSX from "npm:xlsx@^0.20";const inputPath = Deno.args[0];const content = await Deno.readTextFile(inputPath);const rows = parse(content, { columns: true });console.log(JSON.stringify(rows, null, 2));
Claude executa la skill, l'script accedeix als paquets npm, i tot funciona independentment del directori.
Conclusió
El prefix npm: és més verbós. Les banderes de permisos afegeixen cerimònia. La
sintaxi d'importació de Bun és més neta i ràpida. Però la fiabilitat de Deno a
través de diferents estructures de directoris el converteix en la millor opció
per a les skills de Claude Code.
No has de depurar per què una skill funciona en un directori i falla en un altre. No has de documentar "això només funciona fora de projectes amb node_modules". L'script simplement funciona.
Si Bun afegeix una flag per forçar l'autoinstal·lació independentment de la
presència de node_modules, ho reconsideraria. Fins aleshores, la consistència
de Deno guanya.
Referències
- Escrivint Potents Skills de Claude Code amb npx bun — L'exploració original d'aquest enfocament
- Deno — Un runtime modern per a JavaScript i TypeScript
- Compatibilitat npm de Deno
— Com funciona l'especificador
npm: - Documentació d'Autoinstal·lació de Bun — Entenent quan s'activa l'autoinstal·lació
- Documentació de Skills de Claude Code