Beginner · Lesson 9 · 9 min read
Using Packages from pub.dev
Add dependencies, read version constraints, and judge whether a package is safe to depend on before you build your app on top of it.
Updated August 1, 2026
What you will learn
- Add, update and remove dependencies
- Read and choose version constraints
- Evaluate a package before adopting it
- Understand packages vs plugins, and dev dependencies
Flutter's standard library is deliberately small. Almost every real app pulls in packages from pub.dev for HTTP, storage, state management and platform features. Choosing well matters — a dependency is code you did not write but must still maintain.
Adding a dependency
# Preferred: resolves the latest compatible version and edits pubspec for you
flutter pub add http
flutter pub add shared_preferences intl
# A dev-only dependency (tests, code generation, lints)
flutter pub add --dev build_runner
# Remove one
flutter pub remove httpdependencies:
flutter:
sdk: flutter
http: ^1.2.0
shared_preferences: ^2.3.2
intl: ^0.19.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
build_runner: ^2.4.13dependencies ship inside your app. dev_dependencies are used only while developing — test helpers, linters, code generators — and are excluded from the release build.
Version constraints
| Constraint | Means | Notes |
|---|---|---|
^1.2.0 | ≥ 1.2.0 and < 2.0.0 | The default. Accepts compatible updates, blocks breaking ones. |
>=1.2.0 <1.5.0 | An explicit range | Use when you know a later version breaks you. |
1.2.0 | Exactly that version | Pins hard; blocks security fixes too. |
any | Any version at all | Avoid — a breaking release will silently land. |
The caret constraint relies on semantic versioning: the first number changes only on a breaking change. For packages below 1.0.0 the rules shift — ^0.19.0 means >=0.19.0 <0.20.0, because pre-1.0 the second number signals breakage.
Keeping dependencies current
# What is outdated, and what can move within current constraints
flutter pub outdated
# Upgrade within the constraints in pubspec.yaml
flutter pub upgrade
# Upgrade past them, rewriting pubspec to the newest majors
flutter pub upgrade --major-versions
# Fetch what the lockfile already specifies (what CI should run)
flutter pub getJudging a package before you adopt it
Every pub.dev listing shows likes, pub points and download counts. Those are a starting signal, not an answer. Before depending on something, check:
- Last publish date. A package untouched for two years may not support the current Flutter SDK, and will not have been updated for recent platform requirements.
- Open issues and how they are answered. Many unanswered bug reports is a stronger warning than a low score.
- Platform support. The listing shows which platforms are supported. A plugin that is Android-only will block you the day you add iOS.
- Publisher. Packages under
dart.dev,flutter.devandtools.flutter.devare maintained by the Flutter team. Verified publishers are a good sign. - Size of the problem it solves. Do not add a dependency for something twenty lines of Dart would do. Every package is code that can break, conflict, or be abandoned.
- Licence. Check it is compatible with your project, especially for commercial work.
Packages vs plugins
A package is pure Dart — intl, collection, http. A plugin also contains native platform code — camera, shared_preferences, url_launcher. The practical differences matter:
- Plugins usually require a full restart, not a hot reload, when first added.
- Plugins may need platform configuration — permissions in
AndroidManifest.xml, usage descriptions inInfo.plist. - Plugins can fail to work in plain Dart unit tests, because there is no platform to talk to. You mock the channel instead.
- Plugins may not support every platform, including web.
A reasonable starting set
| Need | Common choice |
|---|---|
| HTTP requests | http (simple) or dio (interceptors, retries) |
| Key–value storage | shared_preferences |
| Secure storage | flutter_secure_storage |
| SQLite | sqflite or drift |
| State management | provider, flutter_riverpod or flutter_bloc |
| Routing | go_router |
| Cached network images | cached_network_image |
| Dates and number formats | intl |
| Opening links, mail, dialer | url_launcher |
| Stricter lints | flutter_lints |
Key takeaways
flutter pub addis better than hand-editing pubspec — it picks a correct constraint for you.^1.2.0allows compatible updates; below 1.0.0 the second number is the breaking one.- Check last publish date, open issues and platform support before adopting a package.
- Wrap third-party APIs behind your own thin interface so they can be replaced.
Practice
Evaluate and integrate
Pick a package you have not used — for example url_launcher or cached_network_image. Review its pub.dev page against the checklist above and write down your verdict. Then add it, wrap it in a small service class of your own, and use that class from a screen.
Show hints
- Check the Changelog tab to see how often breaking changes land.
- Note any platform setup the README requires before you write code.