What is the difference between dependencies and dev_dependencies in pubspec.yaml?
#flutter#dart#pubspec#dependencies#packages
Answer
Overview
In Flutter/Dart,
text
pubspec.yaml- — Packages needed at runtime (included in the final app build)text
dependencies - — Packages needed only during development (NOT included in production)text
dev_dependencies
dependencies
Packages listed under
text
dependenciesyaml# pubspec.yaml dependencies: flutter: sdk: flutter # State management provider: ^6.1.2 flutter_bloc: ^8.1.6 # Networking http: ^1.2.2 dio: ^5.7.0 # Local storage shared_preferences: ^2.3.3 sqflite: ^2.4.1 # UI cached_network_image: ^3.4.1 flutter_svg: ^2.0.15 # Navigation go_router: ^14.6.2 # Firebase firebase_core: ^3.8.1 firebase_auth: ^5.3.4
dev_dependencies
Packages listed under
text
dev_dependenciesyaml# pubspec.yaml dev_dependencies: flutter_test: sdk: flutter # Testing mockito: ^5.4.4 bloc_test: ^9.1.7 integration_test: sdk: flutter # Code generation build_runner: ^2.4.13 json_serializable: ^6.8.0 freezed: ^2.5.7 # Linting flutter_lints: ^5.0.0 very_good_analysis: ^6.0.0 # Launcher icons & splash screen flutter_launcher_icons: ^0.14.2 flutter_native_splash: ^2.4.3
Key Differences
| Feature | text | text |
|---|---|---|
| Included in build | Yes (production APK/IPA) | No |
| Available at runtime | Yes | No |
| Increases app size | Yes | No |
| Imported from text | Yes | No |
| Imported from text | Yes | Yes |
| Purpose | App functionality | Testing, code gen, tooling |
The Rule
The official Dart documentation states:
If the dependency is imported from something in your
ortextlib/directories, it must be a regular dependency. If it's only imported fromtextbin/ortexttest/directories, it can and should be atextexample/.textdev_dependency
dart// ✅ In lib/services/api_service.dart — uses regular dependency import 'package:dio/dio.dart'; // dio must be in dependencies // ✅ In test/services/api_service_test.dart — uses dev_dependency import 'package:mockito/mockito.dart'; // mockito can be in dev_dependencies
Common Mistakes
Mistake 1: Putting test packages in dependencies
yaml# ❌ Wrong — mockito is only used in tests dependencies: mockito: ^5.4.4 # ✅ Correct — keep test packages in dev_dependencies dev_dependencies: mockito: ^5.4.4
Mistake 2: Putting code generation in dependencies
yaml# ❌ Wrong — build_runner is a dev tool, not runtime dependencies: build_runner: ^2.4.13 # ✅ Correct dev_dependencies: build_runner: ^2.4.13 json_serializable: ^6.8.0
Mistake 3: Putting runtime packages in dev_dependencies
yaml# ❌ Wrong — provider is used in lib/ code dev_dependencies: provider: ^6.1.2 # ✅ Correct — provider is needed at runtime dependencies: provider: ^6.1.2
Special Case: Code Generation Packages
Code generation packages have a split setup:
yamldependencies: json_annotation: ^4.9.0 # Runtime annotations (used in lib/) freezed_annotation: ^2.4.4 # Runtime annotations (used in lib/) dev_dependencies: json_serializable: ^6.8.0 # Generator (only runs during dev) freezed: ^2.5.7 # Generator (only runs during dev) build_runner: ^2.4.13 # Build tool (only runs during dev)
Key Insight: Keeping dev-only packages in
reduces your production app size and avoids shipping unnecessary code to users. Always ask: "Does my app need this package to run?" If not, it belongs intextdev_dependencies.textdev_dependencies