DART: Libraries and Packages

Dart's standard library provides essential tools for async programming, JSON serialization, file I/O, math, and HTTP. Beyond the standard library, the pub.dev ecosystem offers packages for internationalization, path manipulation, and virtually any other need. Understanding both built-in and third-party libraries is key to productive Dart development.

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

dart
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.

dart
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.

dart
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.

dart
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.

dart
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:

dart
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.

bash
dart pub add http

dart
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 MethodFunction
GEThttp.get(url)
POSThttp.post(url, body: ...)
PUThttp.put(url, body: ...)
PATCHhttp.patch(url, body: ...)
DELETEhttp.delete(url)

intl Package — Internationalization

The intl package provides date/time formatting, number formatting, and message translation for multi-locale apps.

bash
dart pub add intl

dart
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.

bash
dart pub add path

dart
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.

dart
// 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:

dart
// 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:

dart
// 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

LibraryImportKey Features
dart:coreAutomaticTypes, collections, print
dart:asyncimport 'dart:async'Future, Stream, async/await
dart:convertimport 'dart:convert'JSON, UTF-8 encoding
dart:mathimport 'dart:math'Math functions, Random
dart:ioimport 'dart:io'File, Directory, HTTP server
dart:collectionimport 'dart:collection'Queue, LinkedList, etc.