// the find
cfug/dio
A powerful HTTP client for Dart and Flutter, which supports global settings, Interceptors, FormData, aborting and canceling a request, files uploading and downloading, requests timeout, custom adapters, etc.
Dio is the de facto HTTP client for Dart and Flutter, filling the gap that `dart:io`'s `HttpClient` leaves with its awkward API. It handles the things you'd otherwise wire up yourself: interceptor chains, cancellation tokens, FormData with multipart, download progress streams, and per-request timeout overrides. If you're writing a Flutter app that talks to an API, you're probably already using this or will be.
The interceptor model is well-designed — you get separate request/response/error hooks with the ability to resolve or reject from any stage, which makes auth token refresh logic straightforward to implement without hacks. CancelToken uses Dart's cancellation idioms correctly and propagates through the interceptor chain rather than just aborting at the transport layer. The adapter abstraction is genuinely useful: swapping in the native adapter or the HTTP/2 adapter is a one-liner, and the compatibility layer lets you drop in any `package:http`-compatible client as the backend. Test coverage is solid, with a shared `dio_test` package that runs the same suite against all adapters, catching platform divergence that unit tests would miss.
The monorepo structure is clean but the root README is nearly empty — it just lists packages and links elsewhere, so a newcomer has to discover which README is actually the documentation. The web adapter is a separate package you have to opt into, which means web support is easy to miss and `dart:html` vs `dart:io` divergence has historically caused subtle bugs (different error types, different redirect behavior). Breaking changes happen in minor versions per their own compatibility policy, which is an unusual and risky call for a library this widely depended on — check the migration guide before any upgrade. There's no built-in retry mechanism in the core library; you implement it yourself via interceptors, which is fine architecturally but means every team writes slightly different retry logic.