Torna al blog

Bun 1.3: Runtime Full-Stack con Dev Server, MySQL, Redis e Performance 3x

Esplora Bun 1.3: dev server full-stack con HMR, client MySQL e Redis integrati, routing avanzato, build 40% più veloci e miglioramenti Node.js.

Edoardo Midali

Edoardo Midali

Developer · Content Creator

15 min di lettura
Bun 1.3: Runtime Full-Stack con Dev Server, MySQL, Redis e Performance 3x

Bun 1.3 è la release più grande di sempre, trasformando Bun in un runtime JavaScript full-stack completo. Include dev server con hot reloading, client MySQL e Redis integrati, routing avanzato, build 40% più veloci e compatibilità Node.js estesa. Questa release posiziona Bun come soluzione definitiva per applicazioni backend e frontend.

🎯 Novità Principali

Dev Server Full-Stack

Dev server integrato con HMR e React Fast Refresh:

// ✅ Bun 1.3 - Esegui HTML direttamente

// Esegui il tuo file HTML
bun run index.html

// Non è un server statico - usa il bundler nativo!
// - Transpila React, CSS, JavaScript, HTML
// - Hot Module Replacement integrato
// - React Fast Refresh automatico
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <title>My Bun App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module">
      import { createRoot } from "react-dom/client";
      import App from "./App.tsx";

      createRoot(document.getElementById("root")).render(<App />);
    </script>
  </body>
</html>

Hot Module Replacement:

// ✅ HMR con React Fast Refresh

// App.tsx
import { useState } from "react";

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

// Modifica il componente - aggiornamento istantaneo senza refresh!
// Lo stato viene preservato (count mantiene il valore)

Performance del dev server:

# Build performance comparison
# Bun 1.2: 45s (100 pages)
# Bun 1.3: 27s (100 pages) → -40%

# Dev server startup
# Bun 1.2: 2.8s
# Bun 1.3: 1.2s → -57%

# Hot reload
# Bun 1.2: 350ms
# Bun 1.3: 120ms → -66%

Inizializzazione progetto:

# Scaffold nuovo progetto
bun init --react
bun init --react=tailwind
bun init --react=shadcn

# Output:
# ? Select a project template
#   Blank
# ❯ React
#   Library

Client MySQL Integrato

API unificata per MySQL, PostgreSQL e SQLite:

// ✅ Bun 1.3 - Bun.SQL

import { sql, SQL } from "bun";

// Connetti a qualsiasi database con la stessa API
const postgres = new SQL("postgres://localhost/mydb");
const mysql = new SQL("mysql://localhost/mydb");
const sqlite = new SQL("sqlite://data.db");

// Default da variabili d'ambiente
// DATABASE_URL viene usato automaticamente
const seniorAge = 65;
const seniorUsers = await sql`
  SELECT name, age FROM users
  WHERE age >= ${seniorAge}
`;

console.log(seniorUsers);
// [
//   { name: "Alice", age: 70 },
//   { name: "Bob", age: 68 }
// ]

PostgreSQL arrays:

// ✅ sql.array helper

import { sql } from "bun";

// Insert array di valori
await sql`
  INSERT INTO users (name, roles)
  VALUES (${"Alice"}, ${sql.array(["admin", "user"], "TEXT")})
`;

// Update con arrays
await sql`
  UPDATE users
  SET ${sql({
    name: "Bob",
    roles: sql.array(["moderator", "user"], "TEXT"),
  })}
  WHERE id = ${userId}
`;

// JSON/JSONB arrays
const jsonData = await sql`
  SELECT ${sql.array([{ a: 1 }, { b: 2 }], "JSONB")} as data
`;

// Tipi supportati: TEXT, INTEGER, BIGINT, BOOLEAN,
// JSON, JSONB, TIMESTAMP, UUID, INET

Miglioramenti PostgreSQL:

// ✅ Simple query protocol per migration

await sql`
  CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT UNIQUE NOT NULL
  );
  CREATE INDEX idx_users_email ON users(email);
  INSERT INTO users (name, email)
  VALUES ('Admin', 'admin@example.com');
`.simple();

// Disabilita prepared statements
const sql = new SQL({
  prepare: false, // Utile per PGBouncer
});

// Unix domain socket
await using sql = new SQL({
  path: "/tmp/.s.PGSQL.5432",
  user: "postgres",
  password: "postgres",
  database: "mydb"
});

// Runtime configuration
await using db = new SQL("postgres://user:pass@localhost:5432/mydb", {
  connection: {
    search_path: "information_schema",
    statement_timeout: "30s",
    application_name: "my_app"
  },
  max: 1
});

Operazioni dinamiche:

// ✅ Dynamic column operations

const user = {
  name: "Alice",
  email: "alice@example.com",
  age: 30,
};

// Insert solo colonne specifiche
await sql`INSERT INTO users ${sql(user, "name", "email")}`;

// Update campi specifici
const updates = {
  name: "Alice Smith",
  email: "alice.smith@example.com",
};
await sql`
  UPDATE users 
  SET ${sql(updates, "name", "email")}
  WHERE id = ${userId}
`;

// WHERE IN con arrays
await sql`SELECT * FROM users WHERE id IN ${sql([1, 2, 3])}`;

// Estrai campo da array di oggetti
const users = [{ id: 1 }, { id: 2 }, { id: 3 }];
await sql`
  SELECT * FROM orders 
  WHERE user_id IN ${sql(users, "id")}
`;

Client Redis Integrato

Client Redis/Valkey nativo e velocissimo:

// ✅ Bun 1.3 - Builtin Redis

import { redis, RedisClient } from "bun";

// Connetti automaticamente a REDIS_URL o localhost:6379
await redis.set("foo", "bar");
const value = await redis.get("foo");
console.log(value); // "bar"

console.log(await redis.ttl("foo")); // -1 (no expiration)

Operazioni avanzate:

// ✅ Tutti i comandi Redis

// Hashes
await redis.hset("user:1", "name", "Alice");
await redis.hset("user:1", "age", "30");
const name = await redis.hget("user:1", "name");

// Lists
await redis.lpush("tasks", "task1", "task2");
const tasks = await redis.lrange("tasks", 0, -1);

// Sets
await redis.sadd("tags", "javascript", "bun", "redis");
const tags = await redis.smembers("tags");

// 66 comandi totali supportati!

Pub/Sub messaging:

// ✅ Redis Pub/Sub

import { RedisClient } from "bun";

// Client principale
const myRedis = new RedisClient("redis://localhost:6379");

// Subscriber (client separato)
const publisher = await myRedis.duplicate();

await myRedis.subscribe("notifications", (message, channel) => {
  console.log("Received:", message);
  // Received: Hello from Bun!
});

await publisher.publish("notifications", "Hello from Bun!");

Performance Redis:

// ✅ Significativamente più veloce di ioredis

// Benchmark batch operations:
// ioredis: 100ms per 1000 ops
// Bun Redis: 15ms per 1000 ops → 6.6x faster

// Il vantaggio aumenta con batch più grandi:
// ioredis: 500ms per 10000 ops
// Bun Redis: 45ms per 10000 ops → 11x faster

// Features in arrivo:
// - Cluster support
// - Streams
// - Lua scripting

Routing Avanzato

Sistema di routing potente integrato in Bun.serve():

// ✅ Bun 1.3 - Routing full-stack

import { serve, sql } from "bun";
import App from "./myReactSPA.html";

serve({
  port: 3000,
  routes: {
    // SPA catch-all
    "/*": App,

    // API REST
    "/api/users": {
      GET: async () => Response.json(await sql`SELECT * FROM users LIMIT 10`),
      POST: async (req) => {
        const { name, email } = await req.json();
        const [user] = await sql`
          INSERT INTO users ${sql({ name, email })}
          RETURNING *;
        `;
        return Response.json(user);
      },
    },

    // Route parametriche
    "/api/users/:id": async (req) => {
      const { id } = req.params;
      const [user] = await sql`
        SELECT * FROM users WHERE id = ${id} LIMIT 1
      `;
      if (!user) {
        return new Response("User not found", { status: 404 });
      }
      return Response.json(user);
    },

    // File statici
    "/healthcheck.json": Response.json({ status: "ok" }),
  },
});

Development mode con HMR:

// ✅ Dev server con hot reloading

import homepage from "./index.html";
import dashboard from "./dashboard.html";
import { serve } from "bun";

serve({
  development: {
    // Enable Hot Module Reloading
    hmr: true,

    // Echo console logs dal browser al terminal
    console: true,
  },
  routes: {
    "/": homepage,
    "/dashboard": dashboard,
  },
});

// CORS semplificato!
// Frontend e backend nello stesso processo
// Niente più problemi di porte diverse

Compile to Executable

Compila app full-stack in un singolo eseguibile:

# ✅ Bundle frontend + backend

bun build --compile ./index.html --outfile myapp

# Risultato: eseguibile standalone che:
# - Serve l'HTML
# - Include tutto il backend
# - Funziona ovunque senza dipendenze

Performance:

// Full-stack React app compiled with bun build --compile
// serves the same index.html file 1.8x faster than nginx

// Usa con altre feature Bun:
// - Bun.serve() routes
// - Bun.sql
// - Bun.redis
// - Qualsiasi API Bun

// Crea app portabili self-contained!

🚀 Performance Improvements

Build Optimization

# ✅ Build 40% più veloce

# Astro 4: 45s (100 pages)
# Astro 5: 27s (100 pages) (-40%)

# Configurazione build parallele
export default {
  build: {
    concurrency: 10,      // Generazione parallela
    incremental: true,    // Build incrementali
    cache: true,          // Smart caching
  },
};

Image Optimization

// ✅ Ottimizzazione automatica immagini

import { Image } from "bun";

// Automatic WebP/AVIF conversion
// Lazy loading by default
// Responsive images
// 60% size reduction

const optimized = await Image.optimize("hero.jpg", {
  width: 800,
  height: 600,
  format: "webp",
  quality: 80,
});

Bundle Size Reduction

// ✅ Bundle -39% più piccoli

// Astro 4: 85KB main bundle
// Astro 5: 52KB main bundle (-39%)

// Miglioramenti:
// - Tree shaking migliorato
// - Dead code elimination avanzato
// - Chunk splitting ottimizzato

📦 Package Manager

Catalogs per Monorepo

// ✅ Bun 1.3 - Dependency catalogs

// root package.json
{
  "name": "monorepo",
  "workspaces": ["packages/*"],
  "catalogs": {
    "react": "^18.0.0",
    "typescript": "^5.0.0"
  }
}

// packages/ui/package.json
{
  "name": "@company/ui",
  "dependencies": {
    "react": "catalog:react"
  }
}

// Aggiorna una volta, aggiorna ovunque!

Isolated Installs (Default)

# ✅ Installs isolati di default per workspaces

# Previene accesso a dipendenze non dichiarate
# Risolve il problema #1 in monorepo grandi

# Opt-out se necessario:
bun install --linker=hoisted

# Oppure in bunfig.toml:
[install]
linker = "hoisted"

Security Scanner API

# ✅ Scansione vulnerabilità

# bunfig.toml
[install.security]
scanner = "@socketsecurity/bun-security-scanner"
# Installa scanner
bun add -d @socketsecurity/bun-security-scanner

# Scansione automatica durante install
bun install

# Il scanner:
# - Rileva CVE conosciute
# - Identifica pacchetti malevoli
# - Verifica compliance licenze
# - Blocca install se vulnerabilità critiche

Minimum Release Age

# ✅ Protezione supply chain

[install]
minimumReleaseAge = 604800  # 7 giorni in secondi

# Previene installazione pacchetti appena pubblicati
# La community ha tempo di identificare malware

Nuovi Comandi

# ✅ bun why - spiega perché un pacchetto è installato

bun why tailwindcss

# Output:
# tailwindcss@3.4.17
# └─ peer @tailwindcss/typography@0.5.16

# ✅ bun update --interactive - scegli cosa aggiornare

bun update --interactive

# dependencies         Current  Target   Latest
# ❯ □ react            18.3.1   18.3.1   19.1.1
#   □ prettier         2.8.8    2.8.8    3.6.2
#   □ typescript       5.0.0    5.0.0    5.3.3

# ✅ bun info - metadata pacchetto

bun info react

# Output:
# react@19.2.0 | MIT | deps: 0 | versions: 2536
# React is a JavaScript library for building user interfaces.
# https://react.dev/

# ✅ bun audit - scansione vulnerabilità

bun audit
bun audit --severity=high
bun audit --json > report.json

🧪 Testing Improvements

Async Stack Traces

// ✅ Stack traces asincrone migliorate

async function foo() {
  return await bar();
}

async function bar() {
  return await baz();
}

async function baz() {
  await 1;
  throw new Error("oops");
}

try {
  await foo();
} catch (e) {
  console.log(e);
}

// Output Bun 1.3:
// error: oops
//   at baz (async.js:11:9)
//   at async bar (async.js:6:16)
//   at async foo (async.js:2:16)

// Prima: stack trace incompleto!

VS Code Test Explorer

// ✅ Integrazione VS Code Test Explorer

// Installa: Bun for Visual Studio Code extension

// Features:
// - Test nella sidebar
// - Run/debug con un click
// - Errori inline nel codice
// - Nessuna necessità di lasciare l'editor

Concurrent Testing

// ✅ bun test - concurrent tests

import { test } from "bun:test";

// Test concorrenti (max 20 default)
test.concurrent("fetch user 1", async () => {
  const res = await fetch("https://api.example.com/users/1");
  expect(res.status).toBe(200);
});

test.concurrent("fetch user 2", async () => {
  const res = await fetch("https://api.example.com/users/2");
  expect(res.status).toBe(200);
});

// Describe concorrente
describe.concurrent("server tests", () => {
  test("server 1", async () => {
    const res = await fetch("https://example.com/server-1");
    expect(res.status).toBe(200);
  });

  test("server 2", async () => {
    const res = await fetch("https://example.com/server-2");
    expect(res.status).toBe(200);
  });
});

// Test seriale (quando necessario)
test.serial("sequential test", () => {
  expect(1 + 1).toBe(2);
});

Configurazione:

# bunfig.toml
[test]
# Pattern per file concorrenti
concurrentTestGlob = "**/integration/**/*.test.ts"

# Max concurrency
# bun test --max-concurrency=50

Test Randomization

# ✅ Test order randomization

# Run in random order
bun test --randomize

# Output:
# ... test output ...
# --seed=12345
# 2 pass, 8 fail
# Ran 10 tests across 2 files. [50.00ms]

# Reproduce exact order
bun test --seed 12345

🔒 Security Enhancements

Bun.secrets - Encrypted Storage

// ✅ OS-native credential storage

import { secrets } from "bun";

// Store secrets
await secrets.set("api-key", "secret-value");

// Retrieve secrets
const key = await secrets.get("api-key");

// Storage:
// - macOS: Keychain
// - Linux: libsecret
// - Windows: Credential Manager
// - Encrypted at rest
// - Separate da environment variables

CSRF Protection

// ✅ Token generation e verifica

import { CSRF } from "bun";

const secret = "your-secret-key";

// Generate token
const token = CSRF.generate({
  secret,
  encoding: "hex",
  expiresIn: 60 * 1000, // 1 minuto
});

// Verify token
const isValid = CSRF.verify(token, { secret });
console.log(isValid); // true or false

Crypto Performance

// ✅ Miglioramenti crypto massicci

// Benchmark Bun 1.3 vs Bun 1.2:

// DiffieHellman: ~400x faster
// Bun 1.2: 41.15s
// Bun 1.3: 103.90ms

// Cipheriv/Decipheriv: ~400x faster
// Bun 1.2: 912.65µs
// Bun 1.3: 2.25µs

// scrypt: ~6x faster
// Bun 1.2: 224.92ms
// Bun 1.3: 36.94ms

🌐 WebSocket Improvements

RFC 6455 Compliance

// ✅ Subprotocol negotiation

const ws = new WebSocket("ws://localhost:3000", ["chat", "superchat"]);

ws.onopen = () => {
  console.log(`Connected with protocol: ${ws.protocol}`); // "chat"
};

Custom Headers

// ✅ Override special headers

const ws = new WebSocket("ws://localhost:8080", {
  headers: {
    Host: "custom-host.example.com",
    "Sec-WebSocket-Key": "dGhlIHNhbXBsZSBub25jZQ==",
  },
});

// Utile per WebSocket proxati

Automatic Compression

// ✅ permessage-deflate automatico

const ws = new WebSocket("wss://echo.websocket.org");

ws.onopen = () => {
  console.log("Extensions:", ws.extensions);
  // "permessage-deflate"
};

// Compression/decompression automatici
// Riduce dimensione messaggi 60-80% per JSON

🎨 Bundler & Build

Programmatic Compilation

// ✅ Build API - crea executables

import { build } from "bun";

await build({
  entrypoints: ["./app.ts"],
  compile: true,
  outfile: "myapp",
});

// Prima: solo con CLI
// Ora: programmaticamente!

Cross-Compilation

# ✅ Build per diverse piattaforme

bun build --compile --target=linux-x64 ./app.ts --outfile myapp-linux
bun build --compile --target=darwin-arm64 ./app.ts --outfile myapp-macos
bun build --compile --target=windows-x64 ./app.ts --outfile myapp.exe

# Build da qualsiasi piattaforma per qualsiasi piattaforma!

Windows Executable Metadata

# ✅ Metadata Windows

bun build --compile --target=windows-x64 \
  --title="My App" \
  --publisher="My Company" \
  --version="1.0.0" \
  --description="My amazing app" \
  --copyright="© 2025 My Company" \
  ./app.ts

Minification Improvements

// ✅ Minifier più intelligente

// - Rimuove nomi funzioni/classi inutilizzati
// - Ottimizza new Object(), new Array(), new Error()
// - Minifica typeof undefined checks
// - Rimuove Symbol.for() inutilizzati
// - Elimina try...catch...finally morti

bun build ./app.ts --minify --keep-names

🔧 Node.js Compatibility

Worker Enhancements

// ✅ environmentData API

import {
  Worker,
  getEnvironmentData,
  setEnvironmentData,
} from "node:worker_threads";

// Set nel parent thread
setEnvironmentData("config", { timeout: 1000 });

// Crea worker
const worker = new Worker("./worker.js");

// In worker.js:
import { getEnvironmentData } from "node:worker_threads";
const config = getEnvironmentData("config");
console.log(config.timeout); // 1000

node:test Support

// ✅ Supporto node:test

import { test, describe } from "node:test";
import assert from "node:assert";

describe("Math", () => {
  test("addition", () => {
    assert.strictEqual(1 + 1, 2);
  });
});

// Usa bun:test internamente
// Stessa performance, API Node.js

node:vm Improvements

// ✅ VM module potenziato

import vm from "node:vm";

// SourceTextModule - evalua ES modules
// SyntheticModule - crea synthetic modules
// compileFunction - compila JS in funzioni

const script = new vm.Script('console.log("Hello from VM")');
script.runInThisContext();

// Bytecode caching con cachedData
// vm.constants.DONT_CONTEXTIFY

require.extensions

// ✅ Custom file loaders

require.extensions[".txt"] = (module, filename) => {
  const content = require("fs").readFileSync(filename, "utf8");
  module.exports = content;
};

const text = require("./file.txt");
console.log(text); // File contents

// Legacy API ma garantisce compatibilità npm

📊 Performance Metrics

Comparison Table

Feature Before After Improvement
Build time 45s 27s -40%
Dev startup 2.8s 1.2s -57%
Hot reload 350ms 120ms -66%
DiffieHellman 41.15s 103.90ms ~400x
Cipheriv/Decipheriv 912.65µs 2.25µs ~400x
scrypt 224.92ms 36.94ms ~6x
postMessage strings 593ns 593ns 500x *

* Per stringhe grandi (3MB)

🎓 Best Practices

1. Full-Stack Development

// ✅ Backend + Frontend nello stesso processo

import { serve } from "bun";
import App from "./app.html";

serve({
  port: 3000,
  development: { hmr: true },
  routes: {
    "/*": App,
    "/api/*": handleAPI,
  },
});

2. Database Connection

// ✅ Usa Bun.SQL per performance

import { sql } from "bun";

// Automatic pooling
// Type-safe queries
// Zero dependencies
const users = await sql`SELECT * FROM users`;

3. Security First

// ✅ Scanner + Minimum Release Age

// bunfig.toml
[install.security]
scanner = "@socketsecurity/bun-security-scanner"

[install]
minimumReleaseAge = 604800  # 7 giorni

4. Monorepo Management

// ✅ Catalogs + Isolated Installs

{
  "catalogs": {
    "react": "^18.0.0"
  }
}

// Default isolated installs
// Previene phantom dependencies

💡 Conclusioni

Bun 1.3 è una release trasformativa:

Dev Server full-stack con HMR ✅ Client MySQL/Redis integrati ✅ Routing avanzato in Bun.serve() ✅ Build 40% più velociCrypto ~400x più veloceTesting con concurrency e VS Code integration ✅ Security con scanner e encrypted storage ✅ Node.js compatibility estesa

Installa/aggiorna oggi:

# Installa Bun
curl -fsSL https://bun.sh/install | bash

# Oppure aggiorna
bun upgrade

Quando usare Bun 1.3:

  • ✅ Applicazioni full-stack (React/Vue + API)
  • ✅ Backend con MySQL/PostgreSQL/Redis
  • ✅ Monorepo con gestione dipendenze
  • ✅ Test suite performanti
  • ✅ Build e bundling veloci