Dart's library system is what transforms a language into a platform. The standard libraries cover most common programming needs, while the pub.dev ecosystem extends those capabilities with thousands of community and official packages. Understanding the major libraries — what they provide and when to use them — makes you dramatically more productive.
dart:core — The Foundation
dart:core is automatically imported into every Dart program. You never need to import it explicitly. It provides the fundamental building blocks of the Dart language.
Core types provided:
- Numeric types:
int,double,num - Text:
String - Collections:
List,Set,Map,Iterable - Functions and closures
print()for console output- Type system:
Object,dynamic,Null - Exceptions:
Exception,Error, and their subtypes
void main() {
// All of this uses only dart:core (imported automatically)
String greeting = 'Hello, Dart';
int count = 42;
List<String> fruits = ['Apple', 'Banana', 'Cherry'];
Map<String, int> scores = {'Alice': 90, 'Bob': 85};
print(greeting);
print(count);
print(fruits);
print(scores);
// Built-in string manipulation
print(greeting.toUpperCase());
print(fruits.length);
print(scores.containsKey('Alice'));
}
dart:math — Mathematical Operations
The dart:math library provides mathematical functions, constants, and random number generation.
import 'dart:math';
void main() {
// Constants
print(pi); // 3.141592653589793
print(e); // 2.718281828459045
// Trigonometric functions (angles in radians)
double angle = pi / 4;
print(sin(angle)); // 0.7071...
print(cos(angle)); // 0.7071...
print(tan(angle)); // 1.0
// Logarithms and exponentials
print(log(e)); // 1.0
print(pow(2, 10)); // 1024
// Absolute value and rounding
print((-5).abs()); // 5
print(sqrt(16)); // 4.0
print(max(10, 7)); // 10
print(min(10, 7)); // 7
// Random numbers
final random = Random();
int randomInt = random.nextInt(100); // 0 to 99
double randomDouble = random.nextDouble(); // 0.0 to 1.0
bool randomBool = random.nextBool();
print('Random: $randomInt, $randomDouble, $randomBool');
}
dart:async — Asynchronous Programming
The dart:async library provides the core concurrency primitives: Future, Stream, and Completer.
import 'dart:async';
// Future — a value that will be available in the future
Future<String> fetchData() async {
await Future.delayed(const Duration(seconds: 2));
return 'Data fetched!';
}
// Stream — a sequence of asynchronous events
Stream<int> countDown(int from) async* {
for (int i = from; i >= 0; i--) {
yield i;
await Future.delayed(const Duration(seconds: 1));
}
}
void main() async {
// Await a Future
String data = await fetchData();
print(data); // Data fetched!
// Listen to a Stream
await for (int count in countDown(3)) {
print(count); // 3, 2, 1, 0
}
}
Completer
A Completer lets you create a Future whose completion you control manually — useful for wrapping callback-based APIs.
import 'dart:async';
Future<String> delayedResult() {
final completer = Completer<String>();
// Simulate an async callback-based API
Timer(const Duration(seconds: 1), () {
completer.complete('Result ready');
// Or: completer.completeError(Exception('Something went wrong'));
});
return completer.future;
}
dart:convert — Encoding and Decoding
dart:convert provides converters for JSON and UTF-8. It is used constantly for communicating with REST APIs and storing structured data.
import 'dart:convert';
void main() {
// JSON decoding: String --> Dart object
String jsonString = '{"name": "Alice", "age": 30, "active": true}';
Map<String, dynamic> user = jsonDecode(jsonString);
print(user['name']); // Alice
print(user['age']); // 30
print(user['active']); // true
// JSON encoding: Dart object --> String
Map<String, dynamic> newUser = {
'name': 'Bob',
'age': 25,
'hobbies': ['flutter', 'dart'],
};
String encoded = jsonEncode(newUser);
print(encoded); // {"name":"Bob","age":25,"hobbies":["flutter","dart"]}
// UTF-8 encoding
List<int> bytes = utf8.encode('Hello, Dart!');
String decoded = utf8.decode(bytes);
print(decoded); // Hello, Dart!
}
For structured model classes, define fromJson and toJson methods:
class Product {
final int id;
final String name;
final double price;
Product({required this.id, required this.name, required this.price});
factory Product.fromJson(Map<String, dynamic> json) => Product(
id: json['id'],
name: json['name'],
price: (json['price'] as num).toDouble(),
);
Map<String, dynamic> toJson() => {
'id': id,
'name': name,
'price': price,
};
}
Http Package — HTTP Requests
The http package is not part of the Dart standard library, but it is so universally used that it deserves coverage here. It provides a clean API for making HTTP requests.
dart pub add http
import 'package:http/http.dart' as http;
import 'dart:convert';
void main() async {
final url = Uri.parse('https://api.example.com/posts/1');
try {
final response = await http.get(
url,
headers: {'Authorization': 'Bearer your_token'},
);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print('Title: ${data['title']}');
} else {
print('Error: ${response.statusCode}');
}
} catch (e) {
print('Network error: $e');
}
}
| HTTP Method | Function |
|---|---|
| GET | http.get(url) |
| POST | http.post(url, body: ...) |
| PUT | http.put(url, body: ...) |
| PATCH | http.patch(url, body: ...) |
| DELETE | http.delete(url) |
intl Package — Internationalization
The intl package provides date/time formatting, number formatting, and message translation for multi-locale apps.
dart pub add intl
import 'package:intl/intl.dart';
void main() {
final now = DateTime.now();
// Date formatting
final dateFormatter = DateFormat('yyyy-MM-dd');
print(dateFormatter.format(now)); // e.g., 2025-06-01
final prettyDate = DateFormat('EEEE, MMMM d, yyyy');
print(prettyDate.format(now)); // e.g., Sunday, June 1, 2025
// Number formatting
final currencyFormatter = NumberFormat.currency(locale: 'en_US', symbol: '\$');
print(currencyFormatter.format(1234567.89)); // $1,234,567.89
final percentFormatter = NumberFormat.percentPattern();
print(percentFormatter.format(0.856)); // 86%
}
path Package — File Path Manipulation
The path package provides cross-platform utilities for working with file system paths.
dart pub add path
import 'package:path/path.dart' as p;
void main() {
// Join path segments
var fullPath = p.join('home', 'user', 'documents', 'file.txt');
print(fullPath); // home/user/documents/file.txt (or with \ on Windows)
// Get the directory and filename
print(p.dirname(fullPath)); // home/user/documents
print(p.basename(fullPath)); // file.txt
print(p.extension(fullPath)); // .txt
print(p.withoutExtension(fullPath)); // home/user/documents/file
// Check path properties
print(p.isAbsolute('/usr/local')); // true
print(p.isRelative('lib/main.dart')); // true
}
Creating Custom Libraries
You can organize your Dart code into reusable libraries using the library directive.
// file: lib/math_utils.dart
library math_utils;
int add(int a, int b) => a + b;
int subtract(int a, int b) => a - b;
double divide(double a, double b) {
if (b == 0) throw ArgumentError('Cannot divide by zero');
return a / b;
}
double multiply(double a, double b) => a * b;
Using the library in another file:
// file: lib/main.dart
import 'math_utils.dart';
void main() {
print(add(10, 5)); // 15
print(subtract(10, 5)); // 5
print(divide(10.0, 3.0)); // 3.333...
}
Hiding and Showing Imports
Control exactly what you import from a library:
// Import only specific symbols
import 'dart:math' show pi, sqrt;
// Import everything except specific symbols
import 'dart:math' hide Random;
// Import with a prefix to avoid name collisions
import 'package:http/http.dart' as http;
Standard Libraries Summary
| Library | Import | Key Features |
|---|---|---|
| dart:core | Automatic | Types, collections, print |
| dart:async | import 'dart:async' | Future, Stream, async/await |
| dart:convert | import 'dart:convert' | JSON, UTF-8 encoding |
| dart:math | import 'dart:math' | Math functions, Random |
| dart:io | import 'dart:io' | File, Directory, HTTP server |
| dart:collection | import 'dart:collection' | Queue, LinkedList, etc. |