- Bun 1.2 est une version majeure visant un outil de développement JavaScript/TypeScript full-stack, avec une compatibilité Node.js renforcée et l’extension conjointe du runtime, du bundler, des tests et du gestionnaire de paquets
- La validation de compatibilité a été renforcée en exécutant la suite de tests Node.js à chaque modification, avec l’ajout du support de
node:http2,node:dgram,node:cluster,node:zlibetnode:v8 - Les nouvelles API intégrées
Bun.s3etBun.sqlintègrent l’accès au stockage d’objets compatible S3 et à Postgres directement dans le runtime, réduisant la dépendance à des clients externes - Le gestionnaire de paquets remplace le lockfile binaire
bun.lockbparbun.lockau format JSONC, et ajoute.npmrc,bun publish,bun patch,bun outdatedetbun run --filter - Des changements touchent le répertoire de travail de
bun run, la gestion des échecs deBun.build(), la valeur de retour deserver.stop(),bun -pet les valeurs par défaut des sourcemaps ; les projets existants doivent donc vérifier l’impact de migration
Compatibilité Node.js renforcée
- Bun 1.2 modifie son processus d’amélioration de la compatibilité en exécutant la suite de tests Node.js à chaque changement dans Bun
- Auparavant, les bugs étaient corrigés principalement à partir des issues GitHub ou des signalements d’échec à l’exécution de paquets npm, mais cette approche relevait davantage du « whack-a-mole », rendant les gros refactorings difficiles
- Des milliers de fichiers de test du dépôt Node.js ont été portés vers Bun, puis exécutés à chaque commit pour vérifier la compatibilité
- Certains tests Node.js vérifient des détails d’implémentation internes et des messages d’erreur exacts ; Bun remplace donc, dans certains cas, les liaisons internes par ses propres stubs ou adapte les vérifications pour se concentrer sur
nameetcode- Bun cherche autant que possible à reproduire les messages d’erreur de Node.js, mais peut parfois fournir un message plus utile tant que
nameetcoderestent identiques
- Bun cherche autant que possible à reproduire les messages d’erreur de Node.js, mais peut parfois fournir un message plus utile tant que
- Nouveaux modules et fonctionnalités Node.js pris en charge
node:http2: prise en charge de la création de serveurs HTTP/2, nécessaire aussi pour les serveurs gRPCnode:dgram: prise en charge du bind/connect des sockets UDPnode:cluster: possibilité d’exécuter plusieurs instances de Bun pour répartir la charge sur plusieurs cœurs CPUnode:zlib: l’implémentation JavaScript a été réécrite en code natif et devient 2 fois plus rapide que dans Bun 1.1node:v8:getHeapSnapshotetwriteHeapSnapshotpermettent d’inspecter le tas de Bun dans Chrome DevTools
- Le serveur
node:http2est 2 fois plus rapide que Node.js dans Bun 1.2 expresstraite les requêtes HTTP jusqu’à 3 fois plus vite que Node.js grâce aux améliorations de compatibiliténode:httpet aux optimisations du serveur HTTP de Bun- La prise en charge des extensions C++ utilisant l’API C++ de V8 a aussi été ajoutée
- Node.js utilise V8, tandis que Bun repose sur JavaScriptCore, ce qui rend l’implémentation difficile
- Bun implémente l’API C++ publique de V8 au-dessus de JavaScriptCore afin de faire fonctionner des paquets comme
cpu-features - Cette prise en charge de l’API C++ de V8 étant complexe, il peut encore manquer des fonctionnalités pour la plupart des paquets ; le support de paquets comme
node-canvas@v2etnode-sqlite3continue d’être amélioré
API S3 intégrée Bun.s3
- Bun 1.2 ajoute l’API intégrée
Bun.s3pour manipuler un stockage d’objets compatible S3- Elle peut être utilisée avec Amazon S3, Google Cloud Storage, Cloudflare R2 et d’autres services implémentant l’API S3
- La lecture, l’écriture et la suppression de fichiers passent par une API compatible avec le standard Web
Blob
s3.file()renvoie une référence différée à un fichier S3, utilisable comme l’APIFilede Bun avectext(),json(),arrayBuffer()oustream()- Le client S3 de Bun est écrit en code natif, et non en JavaScript
- Par rapport à l’utilisation de
@aws-sdk/client-s3dans Node.js, le téléchargement de fichiers depuis un bucket S3 est 5 fois plus rapide
- Par rapport à l’utilisation de
- Les fonctions d’écriture fournissent
write()etwriter()write()permet d’envoyer des chaînes,Uint8Array,Blob,Response, etc.writer()effectue des uploads multipart pour les gros fichiers
presign()génère une URL présignée autorisant l’envoi d’un fichier spécifique- Cela permet aux utilisateurs d’uploader directement vers S3 sans exposer d’identifiants ni accorder des permissions inutiles sur le bucket
- Avec
Bun.serve(),new Response(s3.file(...))redirige vers une URL présignée au lieu de télécharger le fichier S3 puis de le renvoyer depuis le serveur- Cela réduit l’usage mémoire, le temps de traitement et les coûts de bande passante liés au téléchargement côté serveur
- Les URL
s3://peuvent aussi être utilisées avecBun.file()etfetch()fetch("s3://...")permet d’uploader, de télécharger et de supprimer- Le
S3Clientpar défaut se configure via des variables d’environnement commeAWS_ACCESS_KEY_IDetAWS_SECRET_ACCESS_KEY
Client Postgres intégré Bun.sql
- Bun 1.2 ajoute
Bun.sql, un client SQL intégré prenant en charge Postgres- Bun proposait déjà un client SQLite intégré, et cette version élargit la prise en charge des bases de données SQL
- Une pull request existe aussi pour ajouter la prise en charge de MySQL
Bun.sqlexécute le SQL via un tagged-template literal- Les valeurs JavaScript peuvent être transmises comme paramètres SQL
- L’échappement des chaînes et les prepared statements sont utilisés automatiquement pour prévenir les injections SQL
- Les résultats sont renvoyés sous forme de tableau d’objets utilisant les noms de colonnes comme clés
- L’implémentation s’appuie sur du code natif et sur plusieurs optimisations
- prepared statements automatiques
- pipelining des requêtes
- protocole wire binaire
- pooling de connexions
- mise en cache des structures
- La lecture des lignes est jusqu’à 50 % plus rapide que lorsqu’on utilise des clients Postgres populaires dans Node.js
- L’API s’inspire de
postgres.jset a été conçue pour faciliter la migration du code existant vers le client SQL intégré de Bun
Évolutions du gestionnaire de paquets
- Bun 1.2 remplace le lockfile par défaut, passant du binaire
bun.lockbau fichier textebun.lockbun.lockba contribué à rendrebun installpresque 30 fois plus rapide quenpm, mais son contenu était difficile à consulter sur GitHub, ce qui compliquait la revue des pull requests et la résolution des conflits de fusion- Les outils comme Dependabot avaient aussi du mal à lire le lockfile
bun.lockest un fichier JSONC- Il prend en charge les commentaires et les trailing commas
- Il facilite la lecture des diff de pull request, et les trailing commas réduisent les risques de conflits de fusion
- Les nouveaux projets créent un
bun.lock- Les projets existants avec
bun.lockbcontinuent à prendre en charge le lockfile binaire sans migration automatique bun.lockbrestera pris en charge sur le long terme, etbun addcommebun updatecontinueront à le mettre à jour- Il est possible de migrer vers le nouveau lockfile texte avec
bun install --save-text-lockfile
- Les projets existants avec
bun installest 30 % plus rapide que Bun 1.1, même après le passage au lockfile texte- Il est possible d’utiliser des commentaires et des trailing commas dans
package.jsonrequire()etimport()peuvent aussi lire ce type depackage.json- Comme cette fonctionnalité n’est pas largement prise en charge dans l’ensemble de l’écosystème JavaScript, il est indiqué de l’utiliser « at your own risk »
- La prise en charge de
.npmrca été ajoutée- Bun lit les fichiers
.npmrcà la racine du projet et dans le répertoire personnel - Ils peuvent servir à configurer le registry, les scoped packages et l’authentification à un registry privé
- Bun lit les fichiers
- Nouvelles commandes et nouvelles options pour le gestionnaire de paquets
bun run --filter: exécuter simultanément le même script dans plusieurs workspacesbun outdated: vérifier les dépendances obsolètesbun publish: remplaçant denpm publish, avec prise en charge de l’authentification.npmrc, du packaging en tarball, de l’OTP et des cas limites depackage.jsonbun patch: enregistrer les modifications apportées à une dépendance dans un fichier.patchsouspatches/, puis les appliquer automatiquement lors debun install--omit=dev|optional|peer: exclure les dépendances dev, optional et peer de l’installation- Les certificats CA peuvent être configurés via
bunfig.toml, des flags CLI ou.npmrc - La prise en charge de
bundleDependencieset la conservation de l’indentation depackage.jsonavecbun addont aussi été ajoutées
Améliorations du test runner
bun testprend en charge le reporter JUnit XML- Avec
bun test --reporter=junit --reporter-outfile=junit.xml, il est possible d’envoyer les résultats de test à des outils CI/CD comme Jenkins, CircleCI ou GitLab CI - Le reporting JUnit peut aussi être configuré dans
bunfig.toml
- Avec
- Un reporter LCOV a été ajouté pour la couverture de code
bun test --coverage --coverage-reporter=lcovgénèrecoverage/lcov.info--coverage-dirpermet de changer le répertoire de sortie
- Les inline snapshots sont pris en charge via
expect().toMatchInlineSnapshot()bun test -uou--update-snapshotsmet à jour les snapshots directement dans le fichier de testtoThrowErrorMatchingSnapshot()ettoThrowErrorMatchingInlineSnapshot()sont également disponibles
test.only()fonctionne désormais sans le flag--only- L’API
expect()ajoute des matchers présents dans Jest, Vitest etjest-extendedtoContainValue(),toContainKey(), et la familletoHaveReturned()- Il est possible de passer un message d’erreur personnalisé en deuxième argument
jest.setTimeout()etsetDefaultTimeout()permettent de modifier le timeout de test par défaut du scope courant ou du module
Bundler et fonctions de build
- Bun 1.2 prend en charge les imports HTML
- En passant un fichier HTML à l’option
staticdeBun.serve, Bun bundle automatiquement les balises<script>et<link>du HTML, puis les expose via des routes statiques
- En passant un fichier HTML à l’option
bun build --compileprend en charge la compilation croisée- Il est possible de créer des binaires Windows ou macOS depuis Linux, et inversement
- Les builds Windows peuvent définir une icône et masquer la fenêtre de console
bun build --bytecodegénère un cache de bytecode- Cela peut diviser par deux le temps de démarrage d’applications comme
eslint - Les fichiers
.jsccontiennent le cache de bytecode du fichier.jscorrespondant, et les deux sont nécessaires à l’exécution - Le cache de bytecode peut être 8 fois plus volumineux que le code source, ce qui améliore le temps de démarrage au prix d’un usage disque plus élevé
- Cela peut diviser par deux le temps de démarrage d’applications comme
bun build --format=cjspermet de choisir le format de sortie CommonJS- Auparavant, seul ESM était pris en charge
- Cela facilite la création de bibliothèques ou d’applications destinées à d’anciennes versions de Node.js
- La détection de CommonJS a été améliorée
- Quand un fichier est ambigu, la directive
"use strict"en tête de fichier est utilisée comme ultime heuristique CommonJS require.main === moduleest réécrit enimport.meta.main, ce qui permet son usage avec des instructions import
- Quand un fichier est ambigu, la directive
- L’API de plugins ajoute le hook
onBeforeParse()- Il doit être implémenté non pas en JavaScript, mais sous forme d’addon N-API
- Il permet de manipuler le code source juste avant le parsing avec un surcoût quasi nul dans des langages compilés comme Rust, C/C++ ou Zig
- Il s’agit d’une API avancée destinée aux auteurs de plugins et de frameworks
- Les options de build ont également été étendues
--env="PUBLIC_*"injecte des variables d’environnement dans le bundle- Suppression d’appels de fonctions avec
--drop=console, par exemple - Ajout de banner/footer
Bun.embeddedFiles()permet de voir la liste des fichiers inclus dans un exécutable autonome--ignore-dce-annotationspermet d’ignorer des annotations de dead-code elimination incorrectes--packages=externalpermet de ne pas inclure les dépendances de paquet dans le bundle
Bundling CSS
- Bun 1.2 implémente un nouveau parseur et bundler CSS
- Il est dérivé du travail de LightningCSS, réécrit de Rust vers Zig, puis intégré au parseur JavaScript/TypeScript, au bundler et au runtime de Bun
bun build ./index.csspermet de combiner plusieurs fichiers CSS ainsi que les références@import,urlet@font-faceen un seul fichier CSS- Il est possible d’importer des fichiers
.cssdepuis du code JavaScript et TypeScript- Les CSS importés depuis le graphe de modules JavaScript, ainsi que les règles
@import, sont aplatis en un seul fichier CSS par entrypoint
- Les CSS importés depuis le graphe de modules JavaScript, ainsi que les règles
- L’API
Bun.build()permet aussi de bundler CSS et JavaScript via une même API
Ajouts à l’API runtime de Bun
Bun.serve()prend en charge les routes statiques via la propriétéstatic- le chemin est passé comme clé, et l’objet
Responsecomme valeur - les routes statiques sont jusqu’à 40 % plus rapides qu’un traitement direct dans le handler
fetch() - le body de la réponse, les headers et le code de statut sont mis en cache en mémoire, ce qui évite les allocations JavaScript et le garbage collection
server.reload()permet de recharger les routes statiques
- le chemin est passé comme clé, et l’objet
Bun.udpSocket()fournit des sockets UDP au format de l’API Bunnode:dgramest aussi pris en charge, maisBun.udpSocket()propose une API moderne proche deBun.listen()- il peut envoyer plusieurs datagrammes UDP avec un seul syscall et gère la backpressure de l’OS
Bun.file()prend en chargedelete(),unlink()etstat()stat()renvoie des métadonnées au même format que l’objetStatsdefs.stat()de Node.js- la même API peut aussi être utilisée pour les fichiers S3
Bun.color()fournit le parsing, la normalisation et la conversion des couleurs- prend en charge CSS, les codes couleur ANSI, RGB, HSL, etc.
dns.prefetch()permet de précharger des enregistrements DNS pour réchauffer le cache DNS au démarragedns.getCacheStats()permet de consulter l’état du cache DNS
- Autres utilitaires
Bun.inspect.table(): renvoie une chaîne au format tableau, commeconsole.tableBun.randomUUIDv7(): génère un UUID v7 monotone adapté au tri et aux bases de données
Améliorations du client SQLite
- Le client SQLite intégré à Bun peut mapper les résultats de requête vers des instances de classe avec
query.as(Class)- il est possible d’y ajouter des getters, setters et méthodes
- pour des raisons de performance, le constructor de classe, les initialiseurs par défaut et les champs privés ne sont pas pris en charge
- ce n’est pas un ORM, car il ne gère ni les relations ni la génération de SQL
query.iterate()traite les lignes via un itérateur sans tout charger en mémoire d’un coup- l’objet de requête lui-même peut aussi être parcouru avec une boucle
for
- l’objet de requête lui-même peut aussi être parcouru avec une boucle
- avec l’option
strict, on peut omettre les préfixes$,@,:dans les paramètres de requête- une erreur est levée si un paramètre manque
- le résultat de
db.run()permet de vérifier le nombre de lignes modifiées et l’ID de la dernière ligne inséréechangeslastInsertRowid
- l’option
safeIntegersrenvoie les entiers 64 bits enBigIntau lieu denumbertronqués- elle peut être définie au niveau de la base de données ou de la requête
- la syntaxe JavaScript
usingpermet de fermer automatiquement les statements et la base de données à la sortie du scope
Compiler et exécuter du C depuis JavaScript
- Bun 1.2 ajoute une prise en charge expérimentale pour compiler et exécuter du C depuis JavaScript
- cela passe par l’API
cc()debun:ffi - cela permet d’utiliser des bibliothèques système en C depuis JavaScript sans étape de build séparée
- cela passe par l’API
- Bun embarque
tinycc- contrairement à
gccouclang, il peut compiler du code C simple en quelques millisecondes - le code C peut ainsi être compilé et exécuté à la demande
- contrairement à
- du code C utilisant N-API est également pris en charge
- il fonctionne avec Bun seul, sans étape de build
node-gyp
- il fonctionne avec Bun seul, sans étape de build
Prise en charge de musl et d’Alpine Linux
- Bun 1.2 ajoute des builds Bun pour les distributions Linux utilisant musl libc au lieu de glibc
- ils peuvent être utilisés dans des environnements comme Alpine Linux
- Linux x64 et aarch64 sont pris en charge
- dans Docker, il est possible d’utiliser l’image
oven/bun:alpine - musl permet des images de conteneur plus petites, mais a tendance à être légèrement plus lent que la version glibc de Bun
- sauf raison particulière, il est recommandé d’utiliser glibc
Fonctionnalités du langage JavaScript
- prise en charge des import attributes
- il est possible d’importer explicitement du JSON, du texte, du TOML, etc., comme dans
import json from "./package.json" with { type: "json" } - cela fonctionne aussi avec
import()dynamique
- il est possible d’importer explicitement du JSON, du texte, du TOML, etc., comme dans
- prise en charge de
usingetawait using- à la sortie du scope,
[Symbol.dispose]ou[Symbol.asyncDispose]est appelé pour libérer automatiquement les ressources - cette prise en charge existe dans plusieurs API Bun, dont
Bun.spawn(),Bun.serve(),Bun.connect(),Bun.listen(),bun:sqlite, etc.
- à la sortie du scope,
- Nouvelles API liées aux promesses
Promise.withResolvers(): créepromise,resolveetrejecten une foisPromise.try(): encapsule une fonction synchrone ou asynchrone dans une promise
- API liées aux erreurs et aux tableaux d’octets
Error.isError(): vérifie plus précisément s’il s’agit d’une Error, même en cas de manipulation de la prototype chain ou de contexte cross-realm vianode:vmUint8Array.toBase64()/Uint8Array.fromBase64()Uint8Array.toHex()/Uint8Array.fromHex()
- ajout des iterator helpers
map,flatMap,filter,take,drop,reduce,toArray,forEach,find
- prise en charge de
Float16Array- les tableaux à virgule flottante 16 bits sont moins précis que les 32 bits, mais plus économes en mémoire
Ajouts aux Web API
- prise en charge de
TextDecoderStreametTextEncoderStream- il s’agit des versions streaming de
TextDecoderetTextEncoder - dans Bun,
TextEncoderStreamest jusqu’à 30 fois plus rapide que dans Node.js
- il s’agit des versions streaming de
- prise en charge de l’option
streamdeTextDecoder- même si un chunk ne contient pas un point de code UTF-8 complet, il peut être traité comme partie d’un flux plus large
- ajout de la méthode
bytes()- elle renvoie les données de flux sous forme de
Uint8ArraydepuisResponse,Blob,Bun.file(), etc. - cela réduit l’étape consistant à créer un
Uint8ArrayaprèsarrayBuffer()
- elle renvoie les données de flux sous forme de
- prise en charge de l’upload
fetch()en streaming- utile pour les gros fichiers ou les flux de données dont la longueur de contenu n’est pas connue à l’avance
- implémentation de
console.group()etconsole.groupEnd() - prise en charge de
URL.createObjectURL()- permet de créer une URL depuis un
Blobet de l’utiliser avecfetch(),Workeretimport() - les scripts Worker passent aussi par le transpileur de Bun, donc la syntaxe TypeScript peut être utilisée
- permet de créer une URL depuis un
AbortSignal.any()permet de combiner plusieursAbortSignalpour que si l’un est annulé, le signal parent le soit aussi
Changements de comportement et points d’attention pour la migration
- Le répertoire de travail de
bun runchange- auparavant, il utilisait le répertoire de travail courant du shell
- dans Bun 1.2, il utilise le répertoire parent de
package.jsoncomme répertoire de travail du script - ce changement vise à aligner le comportement sur celui de
npmetyarn
bun testsignale désormais comme échec les uncaught errors ou rejections survenant entre les tests- auparavant, ces erreurs pouvaient ne pas être traitées comme des échecs de test
server.stop()renvoie désormais unPromise<void>- cela permet d’attendre la fermeture des connexions HTTP en cours
Bun.build()rejette désormais en cas d’échec, au lieu d’ajouter l’erreur danslogsd’un résultat résolu- si l’ancien comportement est nécessaire, vous pouvez définir
throw: false
- si l’ancien comportement est nécessaire, vous pouvez définir
bun -pdevient un alias debun --print, pour s’aligner sur Node.js- auparavant, c’était un alias de
bun --port
- auparavant, c’était un alias de
- la valeur par défaut de
bun build --sourcemappasse des source maps inline aux source maps liées- si l’ancien comportement est nécessaire, utilisez
--sourcemap=inline
- si l’ancien comportement est nécessaire, utilisez
Améliorations des performances
- Bun 1.2 inclut des améliorations de performances sur plusieurs chemins d’exécution
node:http2: 2x plus rapide- upload S3 via
node:http: 5x plus rapide path.resolve(): 30x plus rapide- résolution DNS de
fetch(): 2x plus rapide bun --hot: utilisation mémoire réduite de moitiéfs.readdirSync()sur macOS : lecture des petits répertoires 5 % plus rapideString.at(): 44 % plus rapideatob()sur de grandes chaînes en entrée : jusqu’à 8x plus rapide- décompression des données gzip avec
fetch(): 30 % plus rapide Buffer.from(string, "base64")sur de grandes entrées : 6x à 30x plus rapideJSON.parse()sur de grandes chaînes en entrée : 2x à 4x plus rapide, et 6 % plus rapide pour les entrées de type object- débit de certaines applications
Bun.serve(): jusqu’à 2x plus élevé Error.captureStackTrace(): 9x plus rapidefs.readFile()sur de petits fichiers : jusqu’à 10 % plus rapideconsole.log()avec des arguments de type chaîne : 50 % plus rapide
- Sous Windows, le JIT de JavaScriptCore est activé
- auparavant, le JIT n’était disponible que sur macOS et Linux
- JavaScript s’exécute globalement plus vite sous Windows
- par exemple,
Object.entries()est 20 % plus rapide etArray.map()50 % plus rapide
Installation et mise à niveau
- Nouvelles commandes d’installation
curl -fsSL https://bun.sh/install | bashpowershell -c "irm bun.sh/install.ps1 | iex"npm install -g bunbrew tap oven-sh/bunpuisbrew install bundocker pull oven/bun
- Si Bun est déjà installé, effectuez la mise à niveau avec
bun upgrade
1 commentaires
Avis sur Hacker News
Je ne comprends pas pourquoi intégrer une base de données tierce et une bibliothèque S3 externe dans le cœur/la bibliothèque standard.
Ce genre de chose serait mieux sous forme de bibliothèque optionnelle, et ce type de runtime devrait choisir avec beaucoup de prudence ce qu’il inclut dans sa bibliothèque standard.
Ça donne déjà l’impression d’un projet qui met tout et n’importe quoi, façon évier de cuisine.
L’approche batteries incluses est populaire dans beaucoup d’endroits et constitue une voie souvent choisie.
La configuration de TypeScript est difficile, et c’est pareil pour Webpack, S3, Postgres, Jest, etc. ; l’accès simplifié aux fichiers et aux streams est aussi assez intéressant.
Il faudra voir comment les fournisseurs de déploiement distribué se positionnent.
Je peux évidemment me tromper, mais mettre ce type de dépendances dans le cœur/la bibliothèque standard n’a pas vraiment de sens.
Il semble penser qu’en les mettant dans le cœur, il peut optimiser davantage qu’avec des bibliothèques tierces.
Personnellement, je trouve que c’est une mauvaise approche et que Jared est devenu trop ambitieux, mais au final c’est son projet passion.
Dans les termes de Bun : « Bun vise à être un runtime JavaScript cloud-first. Autrement dit, il prend en charge tous les outils et services nécessaires pour exécuter des applications de production dans le cloud », mais cette phrase n’inspire pas vraiment confiance.
Ce choix de conception précis semble encore pire que Node.
Le problème des logiciels financés par le VC a toujours été que ces intégrations cherchent à proposer quelque chose de propriétaire, autrement dit à créer une dépendance.
Jusqu’ici, mon expérience avec Bun a été excellente.
Quand je configurais TypeScript/Jest/React/Webpack sur un nouveau projet, j’appréhendais toujours les changements cassants un peu partout ; avec Bun, c’est géré en interne et, pour mes usages, ça fonctionne simplement sans douleur.
Difficile de me prononcer sur l’intégration de bibliothèques tierces comme S3 ou SQL, mais ils semblent au moins se concentrer sur les éléments les plus courants et les plus demandés.
J’apprécie qu’il apporte une forme de normalité dont l’écosystème d’outils Node.js avait besoin.
Tu sembles sous-estimer à quel point les autres outils ont aussi beaucoup progressé entre-temps.
Pour moi, c’est comme un code de triche pour la productivité.
Il y a bien une petite perte de productivité parce que ChatGPT connaît mal Bun, mais j’aime quand même Bun.
Il y a beaucoup de bonnes choses, mais je m’inquiète de voir certains comportements par défaut devenir trop magiques et implicites.
Si on utilise
new Response(s3.file(...)), au lieu de télécharger le fichier S3 sur le serveur puis de l’envoyer à l’utilisateur, Bun redirige l’utilisateur vers l’URL présignée du fichier S3.Comme valeur par défaut, c’est un choix assez surprenant, et il n’est pas du tout évident de savoir comment le désactiver quand on ne veut pas exposer directement son bucket S3.
Au début, ce projet me donnait envie d’y croire, mais à voir les décisions de conception sporadiques, rendues publiques sur les réseaux, et que je trouve souvent mauvaises, je n’ai pas confiance dans sa direction à long terme.
S’ils étaient restés en v0.x, pourquoi pas, mais après une 1.0, le seuil pour élargir la surface d’API aurait dû être beaucoup plus élevé.
Response(file.stream())Personnellement, ça me donne l’impression d’un comportement à fort effet de bord, et à la lecture on dirait que ça renvoie le contenu du fichier, pas une URL.
Cela dit, je me demande aussi en quoi l’exposition du bucket est gênante.
Comme il s’agit d’une URL présignée, elle ne donne pas non plus de droits d’accès étendus.
Une API explicite comme
Response((file(...).getPresignedURL()))aurait été préférable, ou bien une option permettant d’activer ce comportement via une variable d’environnement ou la configuration de Bun.Batteries incluses fait une grande différence
C’est aussi pour ça que j’aime le fait que les API Web comme Fetch API, les Service Workers, les Web Components, ES6+ ou WebRTC soient désormais natives à la fois dans les runtimes V8 et WebKit
Il faut toutefois une limite
S3 va peut-être trop loin, mais les pilotes SQL ont du sens
Cela dit, la question reste de savoir jusqu’où aller
Il existe énormément de bases de données : faut-il inclure les pilotes de la moitié d’entre elles ?
Rien qu’à ce niveau, cela ferait beaucoup de code supplémentaire, ce qui pourrait ralentir l’exécutable
Et intégrer des API aussi sensibles dans Bun pourrait aussi faire passer la sécurité au second plan
Imaginez qu’un
evalsoit exécuté à cause d’un script ou d’un problème de chemin, et que Bun téléverse alors l’intégralité des fichiers source vers un S3 privé : à ce moment-là, c’est finiJ’ai vu que, selon la façon dont le code est chargé au runtime, cela pouvait être quasiment négligeable
Si le chargement du code n’est déclenché que lorsqu’une instruction
importapparaît, n’y a-t-il pas, en pratique, aucun surcoût en performance ?Même avec une liaison statique, je ne vois pas très bien pourquoi la simple présence du code ralentirait l’exécutable à un niveau significatif
Il y a bien le fait que l’exécutable à charger en mémoire devient littéralement plus gros, mais je doute que cela se traduise par un ralentissement perceptible
Le point central est de savoir qui est responsable de la maintenance de la bibliothèque, et comment cette bibliothèque doit évoluer lorsque SQLite change
S’il y a un bug dans SQLite, comment le corrigera-t-on dans Bun ?
Quelles versions doivent recevoir le correctif ?
Un correctif du runtime peut changer le comportement du code qui tourne dessus : comment gérer les utilisateurs qui ont déjà contourné le problème en s’appuyant sur l’ancien comportement ?
Ce sont des problèmes qu’on peut résoudre dans une certaine mesure, mais ils ont aussi des inconvénients
À partir d’un certain point, on ne parle plus d’un runtime mais d’une plateforme, avec d’autres responsabilités et problèmes qui vont avec
Ce n’est pas un vrai standard du Web, mais beaucoup de gens le traitent de fait comme un standard auquel se conformer
Un client récent utilise Bun en production
J’ai entendu dire que, grâce à sa vitesse et sa simplicité, l’expérience de développement avec Bun est absurdement bonne
L’expérience développeur joue un grand rôle sur le long terme
Si votre base de code ou vos processus sont en désordre, vous perdrez les bons profils, sauf à leur offrir une rémunération de niveau FAANG
Je n’ai pas encore essayé Bun, mais la liste de fonctionnalités est tellement longue que je doute qu’elles soient toutes solides et sans bugs
J’espère me tromper, et je compte l’essayer dans un futur projet
Du point de vue de la gestion de projet, je suis un peu perplexe : pourquoi consacrer du temps au support de S3 alors que ce n’est même pas encore 100 % compatible Node.js ?
Next.js est un très gros écosystème ; pouvoir attirer des clients Next.js permettrait de croître bien davantage que le support de S3
Au quotidien, quelle part de toute la surface d’API Node.js utilisez-vous réellement ?
Et dans quelle mesure dépendez-vous vraiment des cas limites bizarres qu’elle contient ?
Les personnes qui y travaillent ne sont pas des robots non plus
Certaines tâches prennent du temps à comprendre, et pendant ce temps on peut faire autre chose
Une seule personne ne fait pas tout
On dit qu’« attirer des clients Next.js ferait davantage croître le projet », mais croître vers quoi ?
Cela ne rapporte pas d’argent
C’est un projet financé par du capital-risque, et l’objectif n’est pas de fournir Bun gratuitement pour gagner tous les utilisateurs du monde
Zig offre très peu de sécurité mémoire
Si vous référencez une variable qui n’est plus vivante, vous accédez à une zone mémoire arbitraire et sans rapport, au lieu d’obtenir une erreur de segmentation
Apparemment, c’est aussi le cas en mode debug et en mode sécurisé[0]
Est-ce si difficile d’ajouter par-dessus un système de durée de vie mémoire qui marque les noms de variables comme morts et empêche d’y accéder lorsqu’ils le sont ?
Au final, cela revient à dire « n’utilisez pas de comportement indéfini »[1]
C’est pourquoi je ne voudrais rien écrit en Zig sur un serveur Web exposé à Internet
[0] : https://news.ycombinator.com/item?id=41720995
[1] : https://github.com/ziglang/zig/issues/16467#issuecomment-164...
Je l’ai essayé l’an dernier et il plantait sans arrêt
bun addne préservait pas les espaces et l’indentation depackage.json, et qu’il préserve désormais même les indentations les plus étranges, est assez drôleJe ne sais pas qui a demandé ça, ni pourquoi ils ont estimé que cela valait la peine d’y consacrer du code
L’import HTML est impressionnant et très cool
Avec la prise en charge de l’import HTML dans Bun 1.2, ils disent pouvoir remplacer toute la chaîne d’outils frontend par une seule instruction
importOn peut commencer en passant un import HTML à l’option
staticdeBun.serveEst-ce que cela permet le remplacement de modules à chaud, le prétraitement CSS, ou le chargement de plugins propres aux frameworks comme le compilateur de SFC Vue ?
Servir des fichiers statiques n’a rien de vraiment nouveau, donc j’ai l’impression de passer à côté de quelque chose
Je pensais qu’aucun projet n’était aussi voué à l’échec qu’une alternative concurrente à Node.js, mais j’ai bien fait de l’essayer
Je devais créer beaucoup de scripts autonomes pour gérer des fichiers texte et mettre à jour une base SQLite, et j’ai pu utiliser TypeScript,
bun:sqlite[1] etbun $ Shell[2] directement, sans fichier de configuration ni gestion de dépendances npm localesJe l’ai ensuite essayé sur de nouveaux projets JS/TypeScript, et le bundler intégré [3] ainsi que la prise en charge des tests [4] se sont aussi révélés utiles, tandis que l’installation des dépendances se termine instantanément
Le fait que tout fonctionne rapidement et immédiatement améliore vraiment la qualité de vie, et Bun est désormais mon premier choix pour les nouveaux projets JS
[1] https://bun.sh/docs/runtime/shell
[2] https://bun.sh/docs/api/sqlite
[3] https://bun.sh/docs/bundler
[4] https://bun.sh/docs/cli/test
J’étais plutôt du genre : « à quoi bon, tout ça arrivera aussi dans npm l’an prochain »
J’ai fini par essayer Bun, et j’ai vraiment été surpris
Quand les petits éléments de l’expérience développeur s’accumulent, la différence est énorme
Dans mon projet, Bun donne vraiment l’impression d’être la génération suivante
J’ai essayé Bun pour la première fois il y a quelque temps, et l’expérience a été excellente
Tous mes projets sont configurés avec Webpack ou Vite pour utiliser TypeScript, et une fois configuré, ça marche presque parfaitement, mais la configuration elle-même est pénible et n’en vaut pas la peine pour de petits scripts
À l’inverse, Bun a fonctionné immédiatement
Pour essayer d’exécuter du TS « directement » depuis la CLI, j’avais passé 10 à 30 minutes à bricoler avec un outil du genre
node-tsou je ne sais quoi, en affrontant des messages horribles comme « ce n’est pas un module », « impossible d’utiliser import/require », « ESM/CJS », et j’avais essayé toutes les corrections habituelles : changer le type de module danspackage.json, modifiertsconfig, changer la manière d’utiliserimport/requireJ’essayais d’exécuter un script d’environ 200 lignes ; en dernier recours je suis passé à Bun, et ça a fonctionné à merveille
node --experimental-strip-types index.tsSi vous n’avez pas une version récente de Node, le paquet
tsxa bien fonctionné pour moiMieux que
ts-nodeCela dit, dans les deux cas, les informations de type sont simplement jetées, et c’est pareil avec Bun
J’aime la direction prise
En particulier, l’ajout d’une prise en charge native de S3 et Postgres est très pertinent : cela peut constituer une alternative à l’état actuel où l’on « assemble soi-même son framework »
Dans tous les frameworks web comme Rails et Laravel, c’est la norme, et l’écosystème JS peut en tirer un grand bénéfice
À mon avis, la prochaine étape serait une meilleure expérience de test par défaut, avec une bonne gestion des migrations et des schémas, ainsi que de la configuration des factories