Brain
EngineeringFlutter

Packages, Plugins, and Build Modes

What separates a package from a plugin, and what debug, profile, and release builds actually do.

Packages vs plugins

Both ship through pub and both are added the same way. Only one of them contains platform specific code.

Packages

A Flutter package is a collection of Dart code, which may include utility functions, widgets, or entire features, that can be shared and reused across different Flutter projects.

Key characteristics of packages:

  • Contains only Dart code
  • Can be imported and used directly in your Flutter project
  • Does not require platform-specific implementation
  • Typically used for providing new widgets, utility functions, or state management solutions

Examples:

  • provider (for state management)
  • http (for making HTTP requests)
  • intl (for internationalization)
  • flutter_bloc (for BLoC pattern implementation)

Plugins

A Flutter plugin is a special type of package that contains both Dart code and native code (Java/Kotlin for Android, Swift/Objective-C for iOS, JavaScript for web, etc.). Plugins allow Flutter applications to access platform-specific functionality.

Key characteristics of plugins:

  • Contains Dart code and platform-specific native code (Java/Kotlin/Swift/Objective-C)
  • Enables Flutter apps to access native platform features and APIs
  • Communicates between Flutter and native code using platform channels
  • Typically used for accessing device hardware or platform-specific services

Examples:

  • camera (for accessing device camera)
  • geolocator (for GPS and location services)
  • firebase_core (for Firebase integration)
  • flutter_local_notifications (for platform notification systems)

Side by side

FeaturePackagePlugin
ContentOnly Dart codeDart code + Native code
PurposeCode reuse, utilities, widgetsPlatform integration, hardware access
ImplementationPure DartDart + platform-specific code
CommunicationN/AUses platform channels
ComplexityGenerally simplerMore complex due to native code
Use caseUI components, utilities, algorithmsDevice features, hardware access, native APIs

In practical terms, you would use a package when you need additional Dart functionality, and a plugin when you need to access platform-specific features not available in core Flutter.


Build modes

Flutter builds in three modes. Each one trades debuggability against speed and size.

Debug

Debug mode is designed for development and is the default mode when you run flutter run without any flags. In this mode:

  • Hot reload is enabled for rapid iteration
  • Assertions are enabled to catch programming errors
  • Debugging information is included in the binary
  • Service extensions are enabled for DevTools and other debugging utilities
  • Performance is not optimized, prioritizing development speed over runtime performance
  • Works on physical devices, simulators, and emulators

Profile

Profile mode is used for performance testing and analysis:

  • Maintains just enough debugging capabilities for performance profiling
  • DevTools profiling features are available
  • Tracing is enabled to capture performance metrics
  • Not available on simulators/emulators as they don't provide accurate performance measurements
  • Some performance optimizations are applied
  • Activated with: flutter run --profile

Release

Release mode is used for final deployment to end-users:

  • Fully optimized for performance and size
  • All debugging features are disabled
  • Minimal footprint for smaller app size
  • Fastest startup time and runtime execution
  • Service extensions and assertions are disabled
  • Activated with: flutter run --release

These build modes help developers balance between debugging capabilities and performance optimization based on where they are in the development cycle.

On this page