Skip to main content

Menu

System onlineAI Tutorials / 2026

AI Tutorials
Knowledge search

Recent · Popular · Tutorials

  • dart3 tutorials
  • java1 tutorial
  • Javascript3 tutorials
  • Node.js Introduction2 tutorials
  • dartdart · General · In depth
  • JavascriptJavascript · Advanced · In depth
  • JavascriptJavascript · Advanced · Mid
  • JavascriptJavascript · Advanced · Short

Find a tutorial

Tell the assistant what you want to learn. It suggests published chapters.

For example: “I want to learn Rust ownership from the start.” The conversation is kept only in this tab.

0 / 2,000 characters

Enter to send, Shift+Enter for a new line. Do not include personal information.

Chapter 19

Packages, pub, and Everyday Tooling

So far in this tutorial, you have written Dart programs in single files. Real software is different: projects grow, they need reusable parts, and they need tools to test, format, and run them. This chapter introduces the ecosystem that makes Dart practical for real work. You will learn how Dart bund
Level: GeneralLength: In depth4 min read

Read at another depth

Packages, pub, and Everyday Tooling

So far in this tutorial, you have written Dart programs in single files. Real software is different: projects grow, they need reusable parts, and they need tools to test, format, and run them. This chapter introduces the ecosystem that makes Dart practical for real work. You will learn how Dart bundles reusable code into packages (a package is a folder of Dart code plus a small description file), how the pub tool downloads and manages them, and which commands you will use every day.

What pub Is and Why It Exists

Imagine every Dart programmer writing their own code for dates, web requests, or JSON parsing. That would waste enormous effort. Instead, the community shares solved problems as packages, and a central store called [pub.dev](https://pub.dev) hosts them. Anyone can publish there, and anyone can download from there.

The tool that talks to pub.dev is the dart pub command. It reads a description of your project, figures out which packages you need and which versions work together, downloads them, and keeps them organized. The description lives in a file called pubspec.yaml. It is written in YAML (a simple text format that uses indentation to describe structured information).

Anatomy of a Project

Create a project with one command:

Code example in bash
dart create my_app
cd my_app

The generated folder looks like this:

  • pubspec.yaml — the project description: its name, dependencies, and settings.
  • bin/ — code you run directly. The file bin/my_app.dart holds the main function.
  • lib/ — reusable code others (or your own other files) import. Most of a package's code lives here.
  • test/ — automated tests that check your code behaves as expected.
  • .dart_tool/ — internal bookkeeping pub manages. Do not edit it.

A minimal pubspec.yaml looks like this:

Code example in yaml
name: my_app
description: A sample command-line application.
version: 1.0.0
environment:
  sdk: ^3.5.0
dependencies:
  http: ^1.2.0
dev_dependencies:
  lints: ^4.0.0

The two most important sections:

  • dependencies — packages your program needs when it runs.
  • dev_dependencies — packages needed only while developing, such as test tools or lint rules (lints are automatic style checks).

Version Constraints and the Lock File

Notice http: ^1.2.0. The caret symbol ^ means "this version or newer, as long as it stays below 2.0.0." Dart uses semantic versioning (a convention where the first number changes only for breaking changes). So ^1.2.0 accepts 1.2.0, 1.3.1, or 1.9.9, but never 2.0.0, because a new major number may break your code.

When pub resolves your dependencies, it records exact chosen versions in pubspec.lock. This lock file makes builds reproducible (everyone on the team gets identical versions). Commit it to version control for applications; for reusable packages it is usually left out.

The basic commands:

Code example in bash
dart pub get          # download dependencies listed in pubspec.yaml
dart pub add http     # add a dependency and fetch it
dart pub upgrade      # get the newest allowed versions
dart pub outdated     # show which dependencies have newer releases

Import a package's code by its name. If you added http, you can write:

Code example in dart
import 'package:http/http.dart' as http;

Future<void> main() async {
  final response = await http.get(
    Uri.parse('https://example.com'),
  );
  print(response.statusCode);
}

For your own files, import with relative paths or package: paths. Code in lib/util/math.dart inside a project named my_app is imported as package:my_app/util/math.dart.

A Map of Everyday Tooling

A diagram showing pubspec.yaml at the top, with arrows to dart pub get, which fills the pubspec.lock and the package cache. The lib, bin, and test folders all point to dart analyze, dart test, and dart run, which produce the running application.
100%
How a Dart project's files and tools fit together
Show diagram source
flowchart TD
  A[pubspec.yaml] --> B[dart pub get]
  B --> C[pubspec.lock]
  B --> D[package cache]
  E[lib/ code] --> F[dart analyze]
  G[bin/ code] --> H[dart run]
  I[test/ code] --> J[dart test]
  F --> H
  J --> H
  D --> H

The Commands You Will Use Daily

Code example in bash
dart run                 # run the main program (bin/my_app.dart)
dart run bin/other.dart  # run a specific file
dart analyze             # check code for errors and style problems
dart format .            # automatically format all files consistently
dart test                # run the automated tests in test/
dart doc                 # generate API documentation from doc comments
dart fix --apply         # automatically fix common problems

dart format deserves a special mention. It settles all arguments about style: spacing, line breaks, indentation. Teams use it so code reviews focus on logic instead of formatting. Run dart format . before every commit and your whole codebase stays uniform.

dart analyze uses static analysis (examining your code without running it) to catch bugs early: unused variables, type errors, questionable patterns. You can tighten or loosen the rules by adding a analysis_options.yaml file.

Writing and Using Your Own Package

You can publish your own package to pub.dev with dart pub publish, or keep it private. Even without publishing, splitting code into lib/ folders with clean imports makes projects easier to navigate.

To use a package without publishing it, such as a folder sitting next to your project, use a path dependency:

Code example in yaml
dependencies:
  my_helper:
    path: ../my_helper

This is common in large organizations, where several applications share internal packages.

Choosing Packages Wisely

Anyone can publish to pub.dev, so quality varies. Before adding a dependency, check:

  • Publisher: a verified publisher badge means a real organization stands behind it.
  • Popularity and likes: widely used packages are more likely to be maintained.
  • Last publish date: a package untouched for years may be abandoned.
  • Supported SDK version: it must be compatible with your Dart version.

Fewer dependencies generally means fewer things that can break. Add a package when it solves a real problem, not on a hunch.

Common First-Week Mistakes

  • Editing .dart_tool/ by hand. Pub regenerates it; run dart pub get instead.
  • Forgetting dart pub get after pulling teammates' changes, causing "package not found" import errors.
  • Putting runnable scripts in lib/. Keep entry points in bin/.
  • Over-constraining versions, forcing exact versions that conflict with other packages.

Putting It Together

Try the full workflow on a fresh project:

Code example in bash
dart create toolbox
cd toolbox
dart pub add collection

Then edit bin/toolbox.dart:

Code example in dart
import 'package:collection/collection.dart';

void main() {
  final numbers = [3, 1, 4, 1, 5];
  final sorted = numbers.sorted((a, b) => a.compareTo(b));
  print(sorted);
}

Run it with dart run. You have just: created a project, declared a dependency, imported community code, and executed it — the exact loop you will repeat for the rest of your Dart career.

Exercise

A teammate pulls your project from version control and sees "Target of URI doesn't exist: 'package:http/http.dart'". What command fixes it, and why was the error possible?

Show answer

Run dart pub get. The downloaded packages live in a local cache that is not shared through version control; the lock file records versions, but the files themselves must be fetched into each machine's cache before imports can resolve.

Exercise

Your pubspec has http: ^1.2.0. Which of these versions will pub accept: 1.2.0, 1.9.0, 2.0.0, 1.1.0?

Show answer

1.2.0 and 1.9.0 only. The caret allows versions at or above 1.2.0 and below 2.0.0; 2.0.0 is a new major version and 1.1.0 is below the minimum.

Exercise

You want a package that provides lint rules used only during development, never at runtime. Which pubspec section does it belong in?

Show answer

dev_dependencies. Packages there are available while developing and testing but are not bundled with the code you ship.

Spotted a mistake, or code that does not work?

Report an issue

Chapter: Packages, pub, and Everyday Tooling

0 / 2,000 characters

Plain text, for example: the second code sample does not compile. Do not include personal information.

You can't do that