Dart: Dart Package Management

Last updated: 2026-08-26

Dependency management is the project's supply chain — only by managing dependencies well can a project be stable.

1. What You'll Learn


2. A Developer's True Story

(1) Pain Point: Build Failure Due to Dependency Version Conflict

Alice's team used http: ^1.1.0 in their DataPipeline project, but another dependency, api_client, required http: >=0.13.0 <1.0.0. The version constraints were incompatible, causing dart pub get to fail. Worse still, a dependency silently updated a minor version, introducing a breaking change that caused the CI build to fail. The team spent 2 days investigating.

(2) The Solution: Semantic Versioning

Dart uses Semantic Versioning (SemVer) and version constraint syntax to make dependency management predictable. ^1.2.0 means >=1.2.0 <2.0.0, guaranteeing compatibility.

YAML
dependencies:
  http: ^1.2.0       # Compatible with 1.x, safe minor/patch updates
  args: ^2.4.2        # Compatible with 2.x
  csv: ^6.0.0         # Compatible with 6.x

(3) The Benefits


3. Complete pubspec.yaml Configuration

(1) Configuration Structure

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Complete pubspec.yaml

YAML
name: datapipeline
description: A CLI tool for e-commerce data analytics processing million-level orders
version: 1.0.0
homepage: https://github.com/bob/datapipeline
repository: https://github.com/bob/datapipeline
documentation: https://datapipeline.dev/docs

environment:
  sdk: ^3.0.0

dependencies:
  # CLI argument parsing
  args: ^2.4.2
  # HTTP client for API calls
  http: ^1.2.0
  # CSV file parsing
  csv: ^6.0.0
  # SQLite database support
  sqlite3: ^2.4.0
  # Path manipulation utilities
  path: ^1.9.0
  # Logging framework
  logging: ^1.2.0
  # YAML configuration parsing
  yaml: ^3.1.2

dev_dependencies:
  # Testing framework
  test: ^1.24.0
  # Code generation runner
  build_runner: ^2.4.0
  # JSON serialization
  json_serializable: ^6.7.0
  # Lint rules
  lints: ^3.0.0

dependency_overrides:
  # Temporary: resolve version conflict
  # transitive: ^1.0.0

executables:
  datapipeline: datapipeline
Field Required Description
name Yes Package name (lowercase + underscores)
description Yes Package description (60-180 characters)
version No Semantic version number
environment Yes SDK version constraints
dependencies No Runtime dependencies
dev_dependencies No Development-time dependencies
dependency_overrides No Force specific version

4. Version Constraint Syntax

(1) Semantic Versioning

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Version Constraint Syntax

YAML
dependencies:
  # Caret syntax: ^1.2.3 = >=1.2.3 <2.0.0
  package_a: ^1.2.3

  # Range syntax
  package_b: ">=1.2.3 <2.0.0"

  # Minimum version
  package_c: ">=1.2.3"

  # Any version (dangerous!)
  package_d: any

  # Exact version
  package_e: "1.2.3"

  # Git dependency
  package_f:
    git:
      url: https://github.com/user/package_f.git
      ref: main

  # Path dependency (local development)
  package_g:
    path: ../package_g
Syntax Meaning Example Safety
^1.2.3 >=1.2.3 <2.0.0 Most common High
>=1.2.3 <2.0.0 Range constraint Precise control High
>=1.2.3 Minimum version Higher risk Medium
any Any version Not recommended Low
1.2.3 Exact version Pinned High (not flexible)

(2) Version Resolution Rules

SemVer Rule Description Example
Major Version Incompatible API changes 1.x → 2.x
Minor Version Backward-compatible new features 1.2 → 1.3

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Version Conflict and Resolution

YAML
# Scenario: package_a requires http ^0.13.0, package_b requires http ^1.0.0
# This is a MAJOR version conflict - incompatible!

# Solution 1: Update package_a to a version that supports http ^1.0.0
# Solution 2: Use dependency_overrides (last resort)
dependencies:
  http: ^1.2.0

dependency_overrides:
  http: ^1.2.0  # Force specific version

5. Evaluating Packages on pub.dev

(1) Evaluation Criteria

Dimension Metric Weight
Pub Points Platform support/Documentation/Dependency health High
Likes Community recognition Medium
Popularity Usage count Medium
Pub Verified Publisher verified High
Recent Updates Maintenance activity High
Platform Supported platforms As needed

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: DataPipeline Package Selection

YAML
# DataPipeline package selection criteria:
#
# args (pub points: 140/140, likes: 300+)
#   - Official Dart team package
#   - Stable API, well documented
#   - Perfect for CLI argument parsing
#
# http (pub points: 140/140, likes: 1000+)
#   - Official Dart team package
#   - Standard HTTP client
#   - Supports interceptors and streaming
#
# csv (pub points: 130/140, likes: 100+)
#   - Community package
#   - Handles CSV parsing/writing
#   - Active maintenance
#
# json_serializable (pub points: 140/140, likes: 500+)
#   - Google package
#   - Code generation for JSON
#   - Type-safe, AOT compatible

6. Private Packages and Git Dependencies

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Git Dependencies

YAML
dependencies:
  # Public git repository
  custom_client:
    git:
      url: https://github.com/bob/custom_client.git
      ref: v1.0.0  # Tag, branch, or commit

  # Private git repository (SSH)
  internal_sdk:
    git:
      url: git@github.com:bob/internal_sdk.git
      ref: main

  # Specific path within a git repo
  shared_utils:
    git:
      url: https://github.com/bob/monorepo.git
      path: packages/shared_utils
      ref: stable

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Local Path Dependencies

YAML
# For local development and testing
dependencies:
  core_lib:
    path: ../core_lib

  shared_models:
    path: ./packages/shared_models
Dependency Source Syntax Applicable Scenario
pub.dev package: ^1.0.0 Formal dependencies (recommended)
Git git: url: ... Unpublished/private packages
Local Path path: ../local Development/debugging, monorepo

7. Bob's Scenario: DataPipeline Dependency Configuration

▶ Example

TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

: Complete Project Dependencies

YAML
name: datapipeline
description: E-commerce analytics CLI tool for processing million-level orders
version: 1.0.0

environment:
  sdk: ^3.0.0

dependencies:
  # CLI framework
  args: ^2.4.2
  # Console output formatting
  cli_util: ^0.4.1
  # HTTP client
  http: ^1.2.0
  # CSV parsing
  csv: ^6.0.0
  # JSON serialization
  json_annotation: ^4.8.0
  # Path utilities
  path: ^1.9.0
  # Logging
  logging: ^1.2.0
  # YAML config
  yaml: ^3.1.2

dev_dependencies:
  # Testing
  test: ^1.24.0
  # Mocking
  mockito: ^5.4.0
  # Code generation
  build_runner: ^2.4.0
  json_serializable: ^6.7.0
  # Linting
  lints: ^3.0.0
  # Coverage
  coverage: ^1.6.0

8. Complete Example: DataPipeline Dependency Management

DART
// ============================================
// DataPipeline Dependency Management Demo
// Shows how to use key dependencies
// ============================================

import 'package:args/args.dart';
import 'package:path/path.dart' as p;

const String version = '1.0.0';

class DataPipelineCli {
  final ArgParser parser;

  DataPipelineCli()
      : parser = ArgParser()
          ..addFlag('version', abbr: 'v', negatable: false, help: 'Show version')
          ..addFlag('help', abbr: 'h', negatable: false, help: 'Show help')
          ..addOption('input', abbr: 'i', help: 'Input data source')
          ..addOption('output', abbr: 'o', defaultsTo: 'report.json', help: 'Output path')
          ..addOption('format', allowed: ['json', 'csv', 'html'], defaultsTo: 'json')
          ..addFlag('verbose', abbr: 'V', help: 'Verbose logging')
          ..addOption('batch-size', defaultsTo: '10000', help: 'Records per batch');

  Future<void> run(List<String> arguments) async {
    try {
      final results = parser.parse(arguments);

      if (results['help'] as bool) {
        _printHelp();
        return;
      }

      if (results['version'] as bool) {
        print('DataPipeline v$version');
        return;
      }

      final input = results['input'] as String?;
      final output = results['output'] as String;
      final format = results['format'] as String;
      final verbose = results['verbose'] as bool;
      final batchSize = int.parse(results['batch-size'] as String);

      if (input == null) {
        print('Error: --input is required');
        _printHelp();
        return;
      }

      // Use path package for cross-platform paths
      final inputPath = p.normalize(input);
      final outputPath = p.normalize(output);
      final ext = p.extension(inputPath);

      print('=== DataPipeline v$version ===');
      if (verbose) {
        print('Input:      $inputPath (${ext.isEmpty ? "unknown" : ext})');
        print('Output:     $outputPath');
        print('Format:     $format');
        print('Batch size: $batchSize records');
        print('SDK:        ${_getSdkInfo()}');
      }

      print('Processing: $inputPath → $outputPath ($format)');
    } on FormatException catch (e) {
      print('Argument error: ${e.message}');
      print(parser.usage);
    }
  }

  void _printHelp() {
    print('DataPipeline - E-commerce analytics CLI tool');
    print('');
    print('Usage: datapipeline [options]');
    print(parser.usage);
  }

  String _getSdkInfo() {
    // In real project, use dart:io Platform
    return 'Dart 3.x';
  }
}

void main(List<String> arguments) async {
  final cli = DataPipelineCli();
  await cli.run(arguments);
}
TEXT 📖 Display only
> **Output:** Run in local DartPad or with `dart run`. All examples in this Dart course are based on Dart 3.x / Flutter 3.x. Results may vary slightly depending on the SDK version.

Output (dart run bin/main.dart -i orders.csv -o report.json -V):

TEXT 📖 Display only
=== DataPipeline v1.0.0 ===
Input:      orders.csv (.csv)
Output:     report.json
Format:     json
Batch size: 10000 records
SDK:        Dart 3.x
Processing: orders.csv → report.json (json)

❓ FAQ

Q: What is the difference between dependencies and dev_dependencies? A: dependencies are packages needed at runtime; dev_dependencies are only needed during development (testing, code generation, linting). When publishing a package, dev_dependencies are not passed on to users.

Q: What is the difference between ^ and >=? A: ^1.2.0 is equivalent to >=1.2.0 <2.0.0, limiting updates within a major version. >=1.2.0 has no upper bound. ^ is safer and recommended.

Q: What is the difference between dart pub upgrade and dart pub get? A: dart pub get fetches dependencies within the constraints of pubspec.yaml. dart pub upgrade attempts to upgrade to the latest versions within those constraints.

Q: Should pubspec.lock be committed to version control? A: For application projects (CLI, Flutter App), yes, to ensure the team uses identical versions. For library projects (packages), no, to allow users to get the latest compatible version.

Q: How to choose a package on pub.dev? A: Check pub points (≥130 is good), likes, recent update time, and if the publisher is verified. Prefer official Dart/Google packages.

Q: When should I use dependency_overrides? A: Only temporarily when conflicts cannot be resolved through normal version constraints. Long-term use masks underlying problems. Remove it as soon as the issue is resolved.

Q: Are git dependencies safe for production? A: Not recommended. Git dependencies have no version guarantee, and ref can be force-pushed. For formal releases, use versioned packages from pub.dev.


📖 Summary


📝 Exercises

  1. Basic (Difficulty ⭐): Create a project using dart create, add the args and path dependencies, run dart pub get, and inspect the content of the pubspec.lock file.
  2. Intermediate (Difficulty ⭐⭐): Search for the http package on pub.dev, record its pub points, likes, latest version, and supported platforms. Write a package selection evaluation report.
  3. Challenge (Difficulty ⭐⭐⭐): Create a pubspec.yaml file that includes a git dependency and a path dependency, simulating a monorepo development scenario. Use dependency_overrides to resolve a hypothetical version conflict.

← Previous Lesson | Next Lesson →

Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏