---
title: "Packages, Plugins, and Build Modes"
description: "What separates a package from a plugin, and what debug, profile, and release builds actually do."
tags: [flutter, dart, tooling, build]
---

## 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

| Feature        | Package                              | Plugin                                        |
| -------------- | ------------------------------------ | --------------------------------------------- |
| Content        | Only Dart code                       | Dart code + Native code                       |
| Purpose        | Code reuse, utilities, widgets       | Platform integration, hardware access         |
| Implementation | Pure Dart                            | Dart + platform-specific code                 |
| Communication  | N/A                                  | Uses platform channels                        |
| Complexity     | Generally simpler                    | More complex due to native code               |
| Use case       | UI components, utilities, algorithms | Device 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.
