Per anni Postman è stato lo standard di fatto per chi sviluppa e testa API. Leggero, veloce e ricco di funzionalità, era il punto di partenza naturale per qualsiasi sviluppatore che dovesse interagire con un backend. Poi, lentamente, è cambiato. Ogni aggiornamento portava nuove funzionalità orientate alla piattaforma cloud, nuovi livelli di abbonamento, nuove dipendenze da servizi remoti.
Il momento di rottura, almeno per molti, è arrivato quando Postman ha eliminato la modalità scratchpad, quella che permetteva di lavorare localmente senza un account. Da quel momento in poi, usare Postman significa avere un profilo registrato e lasciare le proprie collection sincronizzate verso i server di Postman.
Per chi lavora su API interne, credenziali sensibili o ambienti aziendali con requisiti di compliance, questa non era una semplice scocciatura: era un problema di sicurezza e privacy. Bruno nasce esattamente per risolvere questo problema, un client API open source, completamente offline, che non prevede il concetto di account né di sincronizzazione cloud.
Tutto, tra richieste, variabili, ambienti e script di test, viene salvato come file di testo nella cartella che scegli tu, nel tuo computer. Di conseguenza, una collection Bruno è qualcosa che puoi committare su Git, revisionare con una pull request e gestire con gli stessi permessi che già hai sul tuo repository. A febbraio 2026 è uscita la versione 3.1 e, ad aprile 2026, Bruno ha aggiunto il supporto OAuth 1.0, un builder visuale per GraphQL e una UI ridisegnata per il collection runner.
Perché Postman ha perso la fiducia di molti sviluppatori
Vale la pena capire cosa ha spinto così tanti team a cercare alternative, perché non si tratta solo di nostalgia per una versione più semplice dello stesso strumento. Postman è diventato una piattaforma: offre mocking, documentazione generata automaticamente, ambienti condivisi nel cloud, integrazioni CI/CD e molto altro. Per certi team grandi, con abbonamenti enterprise, tutto questo ha senso. Per la maggior parte degli sviluppatori, invece, queste funzionalità appesantiscono l’applicazione e introducono dipendenze non necessarie.
Il punto più dolente riguarda le collection stesse. In Postman, le collection sono oggetti gestiti dal cloud di Postman. Puoi esportarle in JSON, certo, ma il formato è verboso, non leggibile a colpo d’occhio e non pensato per essere modificato a mano. Quando lavori in team, condividere una collection significa o usare i workspace cloud di Postman (con i relativi permessi e abbonamenti) oppure esportare e importare file JSON manualmente, un flusso di lavoro che rompe qualsiasi integrazione sensata con Git.
Il risultato pratico è che le collection API finiscono per esistere in un posto separato rispetto al codice. Uno sviluppatore aggiunge un endpoint, aggiorna il codice nel repository, ma la collection Postman rimane indietro finché qualcuno non la aggiorna manualmente. Nelle code review non vedi mai le modifiche alle richieste API.
Come funziona Bruno: file, cartelle e il formato Bru
L’idea alla base di Bruno è che una collection è una cartella nel filesystem. Ogni richiesta è un file. Ogni cartella dentro la collection è una sottocartella. Non c’è un database, non c’è un formato binario, non c’è nessun server di sincronizzazione.
Quando apri Bruno e aggiungi una richiesta GET a https://api.esempio.com/users, Bruno crea un file nella cartella della collection. Puoi aprirlo con qualsiasi editor di testo, leggerlo, modificarlo e committarlo su Git come qualsiasi altro file del progetto.
Dalla versione 3.1, il formato predefinito per i nuovi file è YAML (secondo la specifica open source OpenCollection), che risulta ancora più leggibile rispetto al precedente formato proprietario .bru. Un file di richiesta tipico ha questo aspetto:
meta:
name: Get Users
type: http
seq: 1
http:
method: GET
url: "{{baseUrl}}/users"
auth: none
body: none
headers:
- name: Accept
value: application/json
enabled: trueIl file è leggibile, modificabile a mano e versionabile senza problemi. Se aggiungi un header, il diff nel tuo repository Git mostrerà esattamente quella riga aggiunta. Se rinomini una richiesta, il commit lo registra. Se un collega fa una code review e vede che hai cambiato l’URL di un endpoint, può commentarlo direttamente nella pull request.
Gli ambienti (environment) seguono lo stesso principio: sono file nella cartella della collection. C’è inoltre un fattore importante che Bruno gestisce in automatico: quando crei una collection o un workspace, Bruno genera un .gitignore con le impostazioni raccomandate, in modo che i file contenenti variabili segrete (come chiavi API o password) non vengano mai committati per errore.
Installazione e primo utilizzo pratico
Bruno è disponibile per macOS, Windows e Linux. Puoi scaricarlo dal sito ufficiale usebruno.com/downloads oppure, su Linux, installarlo tramite il package manager della tua distribuzione. Su macOS è disponibile anche via Homebrew:
brew install brunoSu Linux, le opzioni di installazione più comuni sono tre:
.debper distribuzioni Debian e Ubuntu.rpmper Fedora e RHEL- AppImage per qualsiasi distribuzione, senza installazione
Su Windows è disponibile un installer .msi.
Una volta avviato, la prima cosa da fare è creare un workspace. Un workspace in Bruno è semplicemente una cartella sul tuo disco che contiene una o più collection. Puoi organizzarlo per progetto, per team o per client, come preferisci.
Crea il workspace, poi crea una collection al suo interno. Bruno ti chiede il nome e la posizione della cartella. A questo punto puoi cominciare ad aggiungere richieste.
Per importare una collection esistente da Postman, vai su ··· > Import Collection > Postman. Bruno legge i file JSON esportati da Postman e li converte nel suo formato. La migrazione non è sempre perfetta; alcune funzionalità avanzate di Postman non hanno un equivalente diretto, ma per la grande maggioranza dei casi funziona senza problemi.
Per gestire le variabili d’ambiente, crea un environment dalla barra laterale, aggiungi le variabili (per esempio baseUrl = https://api.staging.esempio.com) e selezionalo dall’apposito menu in alto a destra. Da quel momento puoi usare la sintassi {{baseUrl}} in qualsiasi campo della richiesta. Se hai variabili da non committare, marcale come “secret”: Bruno le escluderà automaticamente dal file di environment versionato.
Le novità di Bruno v3: workspace, terminale integrato e Git UI
La versione v3, rilasciata a gennaio 2026, ha introdotto alcune modifiche rilevanti che vale la pena conoscere, soprattutto se hai usato versioni precedenti.
I workspace sono ora un elemento di primo livello nell’interfaccia. Nella versione precedente le collection erano entità indipendenti; ora possono essere raggruppate per progetto, team o dominio. Questo rende molto più ordinato il caso in cui hai decine di collection diverse: invece di scorrere una lista piatta, le trovi organizzate in contenitori logici.

Il terminale integrato è una delle aggiunte più comode per chi lavora abitualmente da riga di comando. Puoi aprire un terminale direttamente all’interno di Bruno senza uscire dall’app, utile per eseguire script, controllare la risposta di un comando curl o lanciare bru (la CLI di Bruno) senza cambiare finestra.
La CLI merita una menzione separata. Con bru run puoi eseguire una collection intera da terminale, passare variabili d’ambiente, filtrare per tag, eseguire richieste in parallelo e integrare il tutto in una pipeline CI/CD. Il comando base per eseguire una collection con un ambiente specifico è:
bru run --env stagingSe vuoi passare variabili aggiuntive senza modificare il file di environment:
bru run --env staging --env-var api_key=sk-123abcLa Git UI è stata completamente ridisegnata. Bruno ha da sempre una forte integrazione con Git, visto che le collection sono file e quindi Git funziona naturalmente, ma ora offre anche un’interfaccia grafica per gestire le operazioni di base direttamente dall’app, utile per chi non lavora sempre da terminale.
Bruno: script, test e collection runner
Bruno permette di aggiungere script JavaScript alle richieste: uno script pre-request (eseguito prima di inviare la richiesta) e uno script post-response (eseguito dopo aver ricevuto la risposta). Questi script hanno accesso all’oggetto bru, l’API interna di Bruno, con cui puoi leggere e impostare variabili d’ambiente, modificare gli header della richiesta e molto altro.
Un esempio classico è il flusso di autenticazione. Invece di copiare manualmente il token JWT dopo ogni login, scrivi uno script post-response sulla richiesta /auth/login che estrae il token dalla risposta e lo salva come variabile d’ambiente:
// Script post-response sulla richiesta di login
const data = res.getBody();
bru.setVar("authToken", data.token);Da quel momento, tutte le richieste che usano {{authToken}} nei loro header avranno il token aggiornato automaticamente. Non serve più nessun copia-incolla.
Per i test, Bruno usa un’API familiare a chi ha già usato Postman o anche Chai:
test("Status è 200", function () {
expect(res.getStatus()).to.equal(200);
});
test("La risposta contiene un array di utenti", function () {
const body = res.getBody();
expect(body.users).to.be.an("array");
expect(body.users.length).to.be.greaterThan(0);
});
Il collection runner ora ti permette di eseguire tutte le richieste di una collection in sequenza, visualizzare i tempi di risposta per ciascuna, filtrare per tag e iterare su file CSV o JSON per scenari parametrici. Se stai testando un endpoint di creazione con cento set di dati diversi, prepari un file CSV e il runner esegue la richiesta cento volte, una per riga.
Bruno come strumento per il team
Il vero cambiamento nel modo di lavorare arriva quando decidi di spostare le collection Bruno direttamente dentro il repository del progetto. La struttura tipica è questa:
my-project/
├── src/
├── tests/
├── bruno/ ← cartella della collection
│ ├── environments/
│ │ ├── local.bru
│ │ └── staging.bru
│ ├── users/
│ │ ├── get-users.yml
│ │ └── create-user.yml
│ └── auth/
│ └── login.yml
└── README.mdCon questa struttura, chiunque cloni il repository ha immediatamente a disposizione tutte le richieste API già configurate, con gli ambienti corretti e gli script di test.
Non c’è più il problema del “ma dove sono le collection di Postman del progetto?” Sono nel repository, alla stessa stregua del codice sorgente e dei test automatici.
Nella pipeline CI/CD, puoi aggiungere uno step che esegue bru run --env staging dopo il deploy per verificare che gli endpoint principali rispondano correttamente. È una forma di testing che richiede pochissima configurazione.
Limiti di utilizzo di Bruno
Bruno è un client API, non una piattaforma per l’intero ciclo di vita delle API. Se il tuo team usa attivamente le funzionalità di mocking di Postman, la generazione automatica di documentazione condivisa online o l’integrazione nativa con strumenti come Stoplight o Swagger Hub, Bruno non copre quegli scenari, non direttamente.
Inoltre, il modello “tutto locale” funziona bene se il team usa Git. Se invece lavori in un contesto dove Git è poco usato o il team preferisce ambienti cloud condivisi, la gestione tramite file potrebbe sembrare più macchinosa del previsto.
Un client che prende posizione
Le API devono poter essere gestite localmente, versionabili, senza dipendenze da servizi di terze parti. Questa scelta comporta dei compromessi, ma offre anche una semplicità che si sente nell’uso quotidiano. L’app è veloce, l’interfaccia non è sovraccarica di opzioni, e il modello mentale è immediato: ogni cosa è un file, ogni file è nel tuo filesystem.
Per chi lavora su API in modo regolare, la migrazione da Postman richiede qualche ora al massimo, considerando anche l’importazione delle collection esistenti. Il guadagno immediato è l’eliminazione dell’account obbligatorio e la fine della preoccupazione su cosa viene sincronizzato e dove.
Il guadagno a lungo termine è avere le collection API integrate nel flusso Git del progetto, visibili nelle code review, modificabili con qualsiasi editor e eseguibili da terminale. Non è un punto di arrivo, visto che Bruno continua a svilupparsi con un ritmo di release mensile regolare, ma è già uno strumento maturo se vuoi un client API che lavori con te. Il codice sorgente è disponibile su GitHub sotto licenza MIT, e il download è al link usebruno.com.













