Bruno: Offline-First-API-Client als Open-Source-Alternative zu Postman

Als Postman 2023 ankündigte, die Offline-Nutzung zu streichen und alle Collections zwingend in die Cloud zu migrieren, reagierte die Entwickler-Community mit lautem Protest. Viele suchten sofort nach Alternativen – und Bruno war zur richtigen Zeit am richtigen Ort. Das quelloffene Tool speichert alle Collections als lesbare Textdateien direkt im Dateisystem, kommt ohne Konto aus und funktioniert vollständig offline. Was steckt hinter Bruno, und wann ist es die bessere Wahl gegenüber Postman?

Was ist Bruno?

Bruno ist ein Desktop-API-Client, der von Anoop M D und der Open-Source-Community entwickelt wird. Das Projekt startete 2022 auf GitHub und hat seitdem über 30.000 Sterne gesammelt. Bruno ist unter der MIT-Lizenz veröffentlicht und steht als native Desktop-App für Windows, macOS und Linux bereit. Eine Konto-Registrierung oder Cloud-Verbindung ist zu keinem Zeitpunkt erforderlich.

Das Herzstück von Bruno ist die Entscheidung, Collections nicht in einer proprietären Datenbank oder Cloud zu speichern, sondern als einfache Textdateien im lokalen Dateisystem – im sogenannten Bru-Format.

Collections als Textdateien: Git-freundlich by Design

Jede Anfrage in Bruno wird als einzelne .bru-Datei gespeichert. Eine Collection entspricht einem Verzeichnis; Unterordner werden als Unterverzeichnisse abgebildet. Das sieht in der Praxis so aus:

my-api/
├── auth/
│   ├── login.bru
│   └── refresh-token.bru
├── users/
│   ├── get-all-users.bru
│   └── create-user.bru
└── bruno.json

Das macht Bruno nativ git-kompatibel: Collections können direkt in einem Repository versioniert werden. Änderungen an einer Anfrage sind als sauberer Diff im Pull Request sichtbar. Teams können gemeinsam an Collections arbeiten, ohne eine externe Synchronisierungsinfrastruktur zu benötigen.

Tipp: Lege deine Bruno-Collection direkt im Stammverzeichnis deines API-Projekts an und füge den my-api/-Ordner zur Git-Versionskontrolle hinzu. So sind Code und API-Tests immer synchron – ein Commit deckt beides ab.

Das Bru-Skriptformat

Das Bru-Format ist eine eigens entwickelte, menschenlesbare Beschreibungssprache für HTTP-Anfragen. Eine typische .bru-Datei sieht so aus:

meta {
  name: Create User
  type: http
  seq: 1
}

post {
  url: {{baseUrl}}/users
  body: json
  auth: bearer
}

auth:bearer {
  token: {{authToken}}
}

body:json {
  {
    "name": "Max Mustermann",
    "email": "[email protected]"
  }
}

tests {
  test("Status ist 201", function() {
    expect(res.status).to.equal(201);
  });
}

Das Format ist absichtlich einfach gehalten – keine JSON-Verschachtelung, keine binären Daten, keine versteckten Felder. Jede Datei lässt sich ohne Bruno-Client lesen und verstehen.

Environments und Variablen

Bruno unterstützt mehrere Environments (z. B. Development, Staging, Production), zwischen denen du per Dropdown wechselst. Variablen wie {{baseUrl}} oder {{authToken}} werden pro Environment unterschiedlich befüllt. Umgebungsdateien mit sensiblen Werten (API-Keys, Passwörter) lassen sich als .env-Dateien auslagern und über .gitignore vom Repository ausschließen, ohne dass die Collection-Struktur davon betroffen wird.

Scripting und Tests

Bruno bietet volle JavaScript-Unterstützung für Pre-Request-Skripte und Tests. In Tests stehen Chai-Assertions (expect(res.status).to.equal(200)) und Zugriff auf Response-Body, Header und Cookies zur Verfügung. Für CI/CD-Pipelines gibt es das CLI-Tool @usebruno/cli, mit dem Collections über die Kommandozeile ausgeführt und Testergebnisse als JUnit-XML exportiert werden können:

npx @usebruno/cli run my-api --env Production --reporter junit
Achtung: Bruno unterstützt aktuell noch kein natives GraphQL-Subscription-Handling und keine WebSocket-Verbindungen. Wer diese Protokolle regelmäßig testet, sollte vorab prüfen, ob der aktuelle Entwicklungsstand ausreicht oder ob eine ergänzende Lösung notwendig ist.

Migration von Postman zu Bruno

Bruno bietet eine integrierte Importfunktion für Postman-Collections (JSON-Export v2.1). Über File > Import Collection > Postman lädst du die exportierte JSON-Datei, und Bruno konvertiert alle Anfragen in das Bru-Format. Pre-Request-Skripte und Tests werden dabei weitgehend übernommen, da Bruno ebenfalls JavaScript verwendet. Umgebungsvariablen müssen manuell in Bruno-Environments überführt werden.

Für eine reibungslose Migration empfiehlt sich das schrittweise Vorgehen: zuerst eine einzelne Collection portieren, testen und erst dann alle weiteren Collections migrieren. Die offizielle Migrationsdokumentation ist unter docs.usebruno.com verfügbar.

Vergleich: Bruno vs. Postman vs. Insomnia vs. HTTPie

Merkmal Bruno Postman Insomnia HTTPie Desktop
Offline-Nutzung Vollständig offline Eingeschränkt (Cloud-Pflicht) Eingeschränkt (Cloud-Sync) Vollständig offline
Git-Freundlichkeit Nativ (Textdateien) JSON-Export manuell YAML-Export manuell Eingeschränkt
Preis Kostenlos (Open Source) Free-Tier / ab $14/Monat Free-Tier / ab $8/Monat Kostenlos (CLI) / $99/Jahr (Desktop)
Scripting JavaScript (Chai) JavaScript (pm.*-API) JavaScript Eingeschränkt
Cloud-Sync erforderlich Nein Ja (seit 2024) Optional (aber eingeschränkt ohne) Nein
Konto erforderlich Nein Ja Ja Nein
CI/CD-CLI Ja (@usebruno/cli) Ja (newman) Ja (inso) Ja (httpie CLI)

Fazit

Bruno löst das zentrale Problem, das viele Entwicklerinnen und Entwickler bei Postman stört: die erzwungene Cloud-Abhängigkeit. Durch die Speicherung aller Collections als Textdateien im Dateisystem ist Bruno das erste API-Tool, das sich nahtlos in git-basierte Workflows integriert, ohne zusätzliche Klimmzüge. Die fehlende Account-Pflicht und die vollständige Offline-Nutzbarkeit machen Bruno außerdem zur sichersten Wahl für Projekte mit sensiblen API-Schlüsseln oder Air-Gap-Anforderungen. Wer von Postman wechseln möchte, findet mit der eingebauten Import-Funktion einen überschaubaren Migrationspfad. Einzige Einschränkung: Für WebSockets und GraphQL-Subscriptions ist das Tool noch nicht vollständig gerüstet.

Mehr Informationen und den Download findest du auf usebruno.com.

Häufige Fragen zu Bruno

Muss ich ein Konto erstellen, um Bruno zu nutzen?
Nein. Bruno funktioniert vollständig ohne Registrierung oder Konto. Nach dem Download und der Installation kann es sofort genutzt werden.
Wie versioniere ich Bruno-Collections mit Git?
Lege die Collection in einem Verzeichnis an, das bereits ein Git-Repository ist, oder initialisiere dort ein neues. Alle .bru-Dateien können direkt committed werden. Sensible Umgebungsvariablen exportierst du in eine separate Datei und trägst diese in .gitignore ein.
Kann ich Bruno-Collections in CI/CD-Pipelines ausführen?
Ja. Das offizielle CLI-Paket @usebruno/cli lässt sich per npm installieren und in GitHub Actions, GitLab CI oder Jenkins einbinden. Testergebnisse können als JUnit-XML für Testberichte exportiert werden.
Unterstützt Bruno GraphQL?
Bruno unterstützt einfache GraphQL-Queries und -Mutations. GraphQL-Subscriptions über WebSockets sind noch nicht vollständig implementiert. Für komplexe GraphQL-Workflows empfiehlt sich aktuell ein ergänzendes Tool wie GraphiQL oder Altair.