Leading a successful Flutter application development project often results from the strong organization of the application architecture. Using Flutter packages is an excellent way to group your application files and functional sections into reusable components that make team collaboration easier. This tutorial will take you through all the steps needed to create a custom package for your next Flutter project.
Before explaining how to create a custom package, let’s review why Flutter developers need to use packages and how custom packages are used. The goal of the package is to isolate reusable functionality and make it easily accessible to other parts of your application. There can be multiple custom packages for a single application.
For example, we can create a custom package to handle HTTP network API connections for different buttons to display the results to different screens. A good way to organize your code is to isolate all the connection functionality into a new directory called,
connection. The connection directory becomes the connection package. You can also create another package for animation and organize your custom animations in that package. Each package you create is put into a common directory called
Once the code is isolated in a package, you can make the package accessible to your application in your main project
pubspec.yaml application configuration file. The syntax of the
pubspec.yaml file differs slightly depending on how you distribute your package.
Once the package is made available to the application using
pubspec.yaml, each file that uses the package imports the package using the syntax
Let’s illustrate the process with examples, starting with the
3 Types of Package Dependency Configuration Formats
There are three strategies for building and distributing your custom Flutter package:
- Publish to pub.dev;
- Publish to a GitHub or equivalent as a standalone repository;
- Store the package within your main project repository.
If you publish the package to pub.dev, you can access it from
pubspec.yaml, under dependencies. As my library is not on pub.dev, I’ll show the syntax with the HTTP package.
2. Remote Git Server
In most cases, you don’t need to make your package accessible to a wide group of people. In these cases, you can access the library from the network with the syntax below.
In the example above, the package name is
theta. The package is available on GitHub under the
3. Packages Folder of Your Project
You can also store the package within your main application project folder. If the package name is
theta, then store it in the main project directory under
If the package is stored locally, the
pubspec.yaml syntax is as follows.
Using a Custom Package
In all three methods, you import your custom package into your application to use it.
Custom Package Code
To illustrate what part of the code is from the package, I’ll include a short snippet of the library.
In the example above, the section
Camera.info is a static getter located in the package at
Once the package is created, it is easy to access all the classes and methods in your package.
Recommendation on Distribution Strategy
You should start by putting your package inside of your application repository
packages directory and only use the package for your one application initially. Once the application and package are stable, you can then distribute it on GitHub for other members of your team or organization to use directly from their
After you make the package accessible to other groups and they start to use it, you will need to spend more time with package version management.
Creating a Package
Create a new project. I called my project theta_api_intro_tutorial.
Create a folder called, packages, in the main project top-level directory.
Change into the directory and create a new package. In this example, my package is called,
flutter create --template=package theta_connection
When you create a package with
flutter create, it will automatically create another set of
Under the newly created
lib directory, there is the main
theta_connection.dart file that functions as the central connection point for the rest of the files in your package.
Delete the example code from both
Create a new file to hold the first method of your new package. I’ve called my file
The key learning point for this file is to learn how to include
part of '../theta_connection.dart' to the top of the file. This is the connection point from each file in your package to the main package file and will later allow your application to access the method.
In addition to connecting the file with the method to
theta_connection.dart, you also need to add a connection from
Congratulations, you’ve just created a custom package!
Review of Steps
- Create a package with
flutter create --template=packagename.
- Create a new file for your package functionality and link it to the main package file with
- In the main package file, link to the new file with
Using Your New Package
pubspec.yaml file in your main project directory, add the path for your new package.
Import the package in
main.dart and use it by calling the method
When you press the button, you should see ‘Hello, world’ in the console.
Expanding Your Package
Using this technique, you can add additional directories and files to each new directory. You can also create different packages for different types of functionality.
As your application grows, you will need to manage the state of your application. My previous article, Flutter 2.0 State Management Introduction with Provider 5.0, explains how to manage the state of your Flutter application with the provider.
Strong organization of your application architecture is the key to a successful project. Failure to manage fundamental areas such as functionality and state can lead to delays and in some cases unfinished projects. Effective use of the standard Flutter package system is a great tool to organize your application architecture. To keep development simple, place your packages inside of your main application repository to reduce the complexity of version management for your package. By reducing the complexity of package version management, you increase the chances that you and your team will uses packages, putting everyone on the path to a successful project launch.