๐Ÿ“ฆ Lesson 4: Packages & Libraries

โฑ 25-35 min ๐Ÿ“Š Intermediate ๐Ÿ“– In-depth tutorial ๐Ÿ”— Official Source
1

Why Packages? The Problem They Solve

๐Ÿง  Core Concept

A package is a reusable collection of Dart code with a well-defined public API. Instead of copying utility functions between projects, you create a package once and import it everywhere. Dart's package manager (pub) handles downloading, versioning, and dependency resolution for you.

โŒ Without Packages

  • Copy-paste code between projects
  • Manually track updates across files
  • No version control for shared code
  • Bugs get duplicated
  • Reinventing the wheel constantly

โœ… With Packages

  • Write once, import everywhere
  • Update one source, all projects benefit
  • Semantic versioning built-in
  • Bug fixes propagate automatically
  • 40,000+ packages on pub.dev
๐Ÿ’ก Real-World Analogy: Packages are like npm modules (JavaScript), pip packages (Python), or gems (Ruby). They let you stand on the shoulders of giants instead of writing everything from scratch.
2

Anatomy of a Dart Package

๐Ÿง  Every Dart package follows a standard layout:

Dart enforces conventions that make packages predictable. When you run dart create -t package super_utils, you get this structure:

super_utils/
lib/
๐Ÿ“„ super_utils.dart
src/
๐Ÿ”’ string_utils.dart
๐Ÿ”’ math_utils.dart
๐Ÿ”’ date_utils.dart
test/
๐Ÿ“„ super_utils_test.dart
๐Ÿ“„ pubspec.yaml
๐Ÿ“„ README.md
๐Ÿ“„ CHANGELOG.md
๐Ÿ“„ analysis_options.yaml

๐Ÿ“„ Click a file to see details

Select a file from the tree to see its purpose and example contents.

๐Ÿ”‘ Critical Convention: lib/src/ is Private

Files inside lib/src/ are conventionally private. Package consumers should never import them directly. Instead, you re-export the public parts from your main library file.

import 'package:super_utils/super_utils.dart'; โœ… Correct โ€” uses public API
import 'package:super_utils/src/string_utils.dart'; โŒ Wrong โ€” bypasses public API, may break

This convention lets package authors refactor internal code without breaking consumers.

3

pubspec.yaml โ€” Your Package's Identity Card

๐Ÿง  Every package has one pubspec.yaml file at its root

This file tells Dart your package's name, version, dependencies, and environment requirements. It's the single source of truth for package configuration.

๐Ÿ—๏ธ Interactive Builder

๐Ÿ“„ Generated pubspec.yaml

name: super_utils
version: 1.0.0
description: A collection of useful Dart utilities

environment:
  sdk: ^3.12.0

dependencies:
  http: ^1.3.0
  intl: ^0.19.0

dev_dependencies:
  test: ^1.24.0
  lints: ^5.0.0
๐Ÿ“Œ Understanding Version Constraints:
โ€ข ^1.3.0 means "any version >=1.3.0 and <2.0.0"
โ€ข >=1.3.0 <1.5.0 is an explicit range
โ€ข any accepts any version (avoid this in production)
โ€ข After editing pubspec.yaml, always run dart pub get
4

Designing a Clean Public API with Exports

๐Ÿง  Your main library file acts as the "front door" to your package

Users should only ever import package:your_package/your_package.dart. Inside that file, you use export statements to expose exactly what you want them to use.

Example: The Main Library File

// lib/super_utils.dart โ€” The ONLY file users should import
library super_utils;

// Export public modules
export 'src/string_utils.dart';
export 'src/math_utils.dart';
export 'src/date_utils.dart';

// Keep internal helpers hidden!
// Do NOT export 'src/internal_helpers.dart'

๐ŸŽฎ Toggle Which Files to Export:

๐Ÿ“„ Generated lib/super_utils.dart

library super_utils;

export 'src/string_utils.dart';
export 'src/math_utils.dart';

๐Ÿ“‹ Example: What's Inside a Utility File?

Here's what lib/src/string_utils.dart might contain:

// lib/src/string_utils.dart
// These functions are "private" to the package structure
// but become public when exported from super_utils.dart

String reverse(String str) {
  return str.split('').reversed.join('');
}

int countVowels(String str) {
  return str
    .toLowerCase()
    .replaceAll(RegExp(r'[^aeiou]'), '')
    .length;
}

bool isPalindrome(String str) {
  final cleaned = str.toLowerCase().replaceAll(RegExp(r'[^a-z0-9]'), '');
  return cleaned == reverse(cleaned);
}
5

Managing Dependencies

๐Ÿง  Three types of dependencies in pubspec.yaml

Type Section Example Use
Regular dependencies: Packages your code imports at runtime
Dev dev_dependencies: Testing, linting โ€” only needed during development
Dependency Overrides dependency_overrides: Force a specific version (temporary fix)

Dependency Sources

dependencies:
  # From pub.dev (most common)
  http: ^1.3.0
  
  # From a local path
  super_utils:
    path: ../super_utils
  
  # From a Git repository
  my_package:
    git:
      url: https://github.com/user/my_package.git
      ref: main
  
  # From a hosted private repo
  private_pkg:
    hosted: https://my-private-pub.dev
    version: ^2.0.0

๐Ÿ“Š Dependency Graph

๐Ÿ“ฆ Your App
No dependencies added. Use the buttons below!
6

Dart Workspaces (Multi-Package Projects)

๐Ÿง  When you have multiple related packages, a workspace ties them together

A workspace lets you manage multiple packages in one repository. One dart pub get resolves dependencies for all packages, ensuring consistency.

๐Ÿ“ monorepo/
๐Ÿ“„ pubspec.yaml โ† workspace root
๐Ÿ“ super_utils/
๐Ÿ“„ pubspec.yaml
๐Ÿ“ lib/
๐Ÿ“ cli_app/
๐Ÿ“„ pubspec.yaml
๐Ÿ“ bin/
๐Ÿ“ web_service/
๐Ÿ“„ pubspec.yaml
๐Ÿ“ lib/

Root pubspec.yaml

name: _
publish_to: none

environment:
  sdk: ^3.12.0

workspace:
  - super_utils
  - cli_app
  - web_service
โœจ Workspace Benefits:
  • Single dart pub get for all packages
  • Consistent dependency versions
  • Easier cross-package refactoring
  • Shared analysis options
7

Finding Packages on pub.dev

๐Ÿง  pub.dev is the official Dart/Flutter package repository

With over 40,000 packages, you'll find solutions for HTTP, JSON, databases, CLI tools, and more. Always check package scores (likes, pub points, popularity) before adopting a dependency.

๐Ÿ“ฆ http

A composable, multi-platform, Future-based API for HTTP requests.

โญ 1200+ likes | โœ… High pub points | ๐Ÿ”„ Updated weekly
๐Ÿ“ฆ intl

Internationalization and localization facilities for date/number formatting.

โญ 950+ likes | โœ… High pub points | ๐Ÿ”„ Updated weekly
๐Ÿ“ฆ path

A string-based path manipulation library. Works across platforms.

โญ 850+ likes | โœ… High pub points | ๐Ÿ”„ Updated weekly
๐Ÿš€

Practice Projects

Apply what you've learned by building these hands-on projects.

๐Ÿ“ฆ Project 1 ๐Ÿ“ฆ Project 2

๐ŸŽฏ Package Master Quiz

Score: 0/6 | Hints: 3

Loading question...