When building modern Flutter applications, handling HTTP requests efficiently is essential. The Dio package offers a complete solution with powerful features like interceptors, request cancellation, file uploading, and more. In this tutorial, you’ll learn how to use Dio in Flutter with a full working example, step-by-step.
This guide is updated for 2025, following the latest Flutter and Dio best practices.
What is Dio in Flutter?
Dio is an advanced HTTP client for Dart and Flutter. It provides a rich set of features that simplify networking tasks such as REST API calls, form data submission, and file handling.
Why Use Dio Instead of http?
While Flutter’s built-in http
package is simple, it lacks many advanced capabilities. Dio solves this by offering:
- Global configuration
- Request/response interceptors
- File uploads and downloads
- Error handling and retries
- Request cancellation
- Type-safe generic response handling
Installing Dio in Flutter
To install Dio, open your pubspec.yaml
and add:
dependencies:
dio: ^5.4.0
Run:
flutter pub get
Full Example: Using Dio in Flutter (2025)
Let’s build a complete example where we:
- Fetch a list of posts from a public API
- Display them in a
ListView
- Handle errors gracefully
Step 1: Create a Dio Client
import 'package:dio/dio.dart';
class ApiService {
final Dio _dio = Dio(BaseOptions(
baseUrl: 'https://jsonplaceholder.typicode.com/',
connectTimeout: Duration(seconds: 5),
receiveTimeout: Duration(seconds: 5),
));
Future<List<dynamic>> fetchPosts() async {
try {
final response = await _dio.get('/posts');
return response.data;
} on DioException catch (e) {
throw Exception('Failed to fetch posts: ${e.message}');
}
}
}
Step 2: Use the Service in a Widget
import 'package:flutter/material.dart';
import 'api_service.dart'; // Import the file where ApiService is defined
class PostListScreen extends StatefulWidget {
@override
_PostListScreenState createState() => _PostListScreenState();
}
class _PostListScreenState extends State<PostListScreen> {
late Future<List<dynamic>> _posts;
@override
void initState() {
super.initState();
_posts = ApiService().fetchPosts();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Dio API Example")),
body: FutureBuilder<List<dynamic>>(
future: _posts,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(child: CircularProgressIndicator());
if (snapshot.hasError)
return Center(child: Text('Error: ${snapshot.error}'));
final posts = snapshot.data!;
return ListView.builder(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
return ListTile(
title: Text(post['title']),
subtitle: Text(post['body']),
);
},
);
},
),
);
}
}
Output:
This will display a list of posts fetched from an external API using Dio. You’ll see a loading indicator, followed by the list once loaded. If an error occurs, it will be displayed in the UI.
Additional Features of Dio
Interceptors
Intercept requests and responses globally.
dio.interceptors.add(LogInterceptor(
requestBody: true,
responseBody: true,
));
Canceling a Request
CancelToken cancelToken = CancelToken();
dio.get('/posts', cancelToken: cancelToken);
// To cancel:
cancelToken.cancel("Request was cancelled");
Uploading a File
FormData formData = FormData.fromMap({
"file": await MultipartFile.fromFile("path/to/image.jpg"),
});
final response = await dio.post("/upload", data: formData);
Best Practices for Using Dio
- Create a singleton instance of Dio for your app
- Use interceptors for token handling and logging
- Handle exceptions using try-catch and
DioException
- Use FormData for multipart requests
- Use
CancelToken
to prevent memory leaks during navigation
Read Artilcles: Dio Package in Flutter – Features & Use Cases (2025 Guide)
Frequently Asked Questions (FAQs)
Dio is a feature-rich HTTP client for Dart used in Flutter to handle API requests, uploads, and advanced networking features.
Use try-catch
blocks and catch DioException
to handle errors like timeouts, server errors, or network issues.
Yes, Dio supports multipart file upload and allows you to track progress using onSendProgress
and onReceiveProgress
.
Yes, for medium to large applications, Dio offers better structure, configuration options, and advanced features not available in the http
package.
Yes. You can implement retry logic manually or use packages like dio_retry
.
Conclusion
Dio is a production-ready HTTP client for Flutter apps in 2025. With features like interceptors, cancellation, and form data handling, it provides everything needed for real-world networking. Whether you are building an eCommerce app or a RESTful backend consumer, Dio is a powerful choice.
Integrate Dio today in your Flutter project to simplify your API logic and improve maintainability.