Found 2 articles
I switched from Postman to Bruno for API testing
- Hank
- 02 Sep, 2026
I recently switched from Postman to [Bruno](https://www.usebruno.com/) for API testing and development. After using Postman for years, this change has been surprisingly refreshing. Here's why I made the switch and what I like about Bruno.## Why I left PostmanPostman is a powerful tool, but over time, a few things started bothering me:- **Cloud-first mentality**: Everything pushes you toward cloud storage and syncing. While you can work locally, it feels like a second-class citizen. - **Performance**: Postman can feel sluggish, especially when dealing with large collections or complex environments. - **Pricing**: The free tier is decent, but paid features can add up if you want team features and advanced functionality. - **Bloat**: There's a lot of UI and features I rarely use, which adds unnecessary complexity.## Why Bruno clicked for meBruno felt like a breath of fresh air because it's built differently:### Local-first, file-based collectionsBruno stores your API collections as plain text files (JSON or TOML format). This means: - Collections live in your project directory, not in the cloud - You can version control them with Git - No vendor lock-in or syncing confusion - It's simple and transparent### Lightweight and fastBruno is lightweight and snappy. The UI is clean and focused on what matters: building and testing API requests.### Open source and transparentBruno is [open source on GitHub](https://github.com/usebruno/bruno), which gives me confidence in the tool's longevity and the ability to contribute or fork if needed.### Works offlineSince everything is local-first, Bruno works perfectly offline without any cloud dependency or sync issues.### Environment variables and scriptingBruno has solid support for environment variables and pre-request/post-response scripting, similar to Postman but with a simpler interface.## The drawbacksTo be fair, Bruno isn't perfect:- **Smaller ecosystem**: Being newer and more niche, there are fewer integrations and plugins compared to Postman - **Team collaboration**: If you need real-time team collaboration, Postman's cloud features have an advantage - **Learning curve**: If you're used to Postman's specific workflow, there's a bit of adjustment## My workflow nowMy typical workflow with Bruno:1. Create a new collection in my project directory 2. Add requests organized by feature or endpoint 3. Define environment variables for different scenarios (dev, staging, production) 4. Write pre-request scripts to generate dynamic data or tokens when needed 5. Commit the collection to Git alongside my codeThis feels more aligned with how I work. Collections are part of my project, not separate artifacts floating in the cloud.## VerdictIf you value simplicity, local-first workflows, version control integration, and don't need heavy team collaboration features, Bruno is worth trying. It's especially great if you're already comfortable with tools that store config as files (like Docker Compose, Terraform, etc.).Give Bruno a shot—you might find it's the API testing tool you didn't know you were missing.
Read MoreA Data Safety Incident in My App
- Hank
- 03 Oct, 2026
I recently dealt with a data safety incident in an app I built with help from DeepSeek. For a while, the app could show an outdated local snapshot when it failed to load the latest server data. The screen looked normal, but a later save could treat that old snapshot as current and overwrite newer records. Some saved household data had to be restored manually.The immediate failure was only part of the problem. The app had no clear way to distinguish fresh, authoritative data from a local fallback, and its save behavior could replace more server data than the user had actually changed. A temporary sync problem had quietly become a data integrity problem.## What I changedI changed the app so ordinary saves update the records they receive instead of replacing an entire collection. Full replacement is now reserved for an explicit setup operation. I also reduced the number of separate database operations needed to load and save data, making the sync path less fragile as the amount of data grows.Most importantly, the client now knows whether its data has been confirmed by the server. If it has not, changes that could overwrite server data are blocked, and the interface makes the sync problem visible with a retry option. The app also records completed migrations on the server, so they do not depend on one browser's local storage.I added recovery and deployment safeguards, too: regular backups, diagnostics, and a smoke check that can catch an unexpected drop in saved records before a release is considered healthy.## What I learnedI used DeepSeek while building the app, and it helped me move quickly. But AI assistance does not change who is responsible for the behavior that ships. I still need to understand the assumptions in generated code, especially around persistence, retries, and what happens when a request fails.The biggest lesson is that cached data must not quietly impersonate confirmed data. A screen can look perfectly healthy while its underlying state is stale. And a save operation should not be more destructive than the user's intent: updating a few records should not put unrelated records at risk.I also learned to test failure paths as carefully as the happy path. A failed sync, a larger-than-usual dataset, or a fresh browser should be ordinary test scenarios, not surprises discovered after deployment. Backups and deployment checks matter, but the strongest protection is making unsafe writes impossible in the first place.This incident was stressful, but it pushed me to make the app more honest about its state and more careful with user data. Building quickly is useful; building systems that fail safely is part of finishing the work.
Read More