Creating and Publishing a Flutter Package

In this tutorial, you’ll learn how to create and publish your own Dart packages to be used in Flutter apps. By Edson Bueno.

Leave a rating/review
Download materials
Save for later
Share

Every three minutes, a new Flutter package pops up on pub.dev (according to the same source that revealed 73.6% of all statistics are made up on the spot). True or not, it’s very believable. So what are you waiting for? Why not join the club and become a package publisher? :]

Some advantages of being a package publisher:

  • You’ll learn a ton about open source project: documentation, versions, releases, issues, licenses, CHANGELOG and README files and more!
  • It’s a great accomplishment to add to your resume.
  • You’ll meet new people who are using your package or are helping you maintain it.
  • Your package can help develop many production apps.
  • You’ll be giving back to the Flutter community.

By the end of this tutorial, you’ll learn everything you need to go from package user to package creator, including how to:

  • Stand out on pub.dev
  • Document your package
  • Structure your package files
  • Create an example project
  • Get package ideas
Note: This article assumes you’ve used packages from pub.dev and are comfortable entering commands on a terminal. If you’re new to Flutter, read Getting started with Flutter first.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.

Unzip the downloaded file and, with Android Studio 4.1 or later, open the project folder starter/yes_we_scan. You can use Visual Studio Code instead, but you might need to tweak some instructions to follow along.

Download the dependencies with Pub get, then build and run your project. If everything went OK, you should see something like this:

Sample app scanning a bar code

Note: The tutorial app uses the camera to capture a QR code. As such, the app requires running on a physical Android or iOS device.

Knowing the Project

The app above could easily be the most uninteresting bar code scanner if it weren’t for two things:

  1. The name: Yes We Scan
  2. The file lib/utils/focus_detector.dart

In this file, you’ll find a widget named FocusDetector.

When you wrap any widget of yours with FocusDetector, you can register callbacks to know whenever that widget appears or disappears from the screen — which happens, for example, when the user navigates to another screen or switches to another app.

Note: Notice that the word focus refers to the user’s focus — not the camera’s or the keyboard’s, as in FocusNode.

If you’ve done native mobile development, think of FocusDetector as a Flutter adaptation of Android’s onResume() and onPause() or iOS’s viewDidAppear() and viewDidDisappear().

Setting the Goal

Yes We Scan leverages FocusDetector to turn on and off the camera as the user leaves and returns to the main screen. Other applications of FocusDetector could include:

  • Turning on and off the GPS or Bluetooth
  • Syncing data with a remote API
  • Pausing and resuming videos

Yes We Scan is here to show that even seemingly boring projects have something to offer to the community.

So from now on, your focus (pun intended) will be on transforming focus_detector.dart, the file, into Focus Detector, the package.

Note: The package focus_detector is already published on pub.dev. This tutorial will go through the entire process as if it weren’t.

And to put you in a good mood, you’ll start by doing something all developers love: documenting.

Documenting

Pub.dev generates a documentation page for every published package. You can find a link to it on the right panel of the package’s pub.dev page:

Directions for the package's documentation on pub.dev

To enhance this document with your own words, you have to place special comments above your public classes, functions, properties and typedefs in your code. Why special? Because they use three slashes (///) instead of two.

Using Doc Comments

Open lib/utils/focus_detector.dart and replace the comment:

// TODO: Document [FocusDetector].

with this documentation comment:

/// Fires callbacks every time the widget appears or disappears from the screen.

Doc comments can be as big as you want — you can even include code snippets and hypertext links. The only requirement is that the first paragraph should be a single-sentence descriptive summary like you did above.

To make sure this gets tattooed on your brain, do it once again by replacing:

// TODO: Document [onFocusGained].

with:

/// Called when the widget becomes visible or enters foreground while visible.

You can peek here to see how these comments end up looking in the docs. For more information about documentation comments, check out Effective Dart: Documentation.

It’s time to leave Yes We Scan aside for a while to work on your spinoff project.

Creating the Project

On your Android Studio’s menu bar, click FileNewNew Flutter Project. Then, select Flutter Package and click Next.

Now, follow the instructions to fill in the fields:

  • Project name: Type in focus_detector.
  • Flutter SDK path: Make sure the default value is the right path to your Flutter SDK.
  • Project location: Choose where you want to store your project.
  • Description: Type in Detects when your widget appears or disappears from the screen.

Click Finish and wait for Android Studio to create and load your new project.

Note: Pub.dev shows the Description both on search and individual package pages. You can change this value later in your pubspec.yaml.

Understanding Packages

You may not know it, but you’ve been creating packages for a while.

A Dart package is nothing but a directory with a pubspec.yaml. Does that remind you of all the apps you’ve created until now? The thing is, there are two types of packages:

  • Application Packages: Those you know very well, with a main.dart file.
  • Library Packages: Shortened to Packages. These are the subject of this tutorial.

What about Flutter Package vs. Dart Package? Flutter Package is only an alias used by the community when referring to a Dart Library Package for Flutter apps.

This raises the next question: What on Earth is a library?

Understanding Libraries

A library is a collection of functions, classes, typedefs and/or properties.

Every time you create a Dart file, you’re making a library. For example, the public elements of an alert_utils.dart file form an alert_utils library. That’s why your Dart files go under a lib directory.

You can also create a library by creating a file that gathers other libraries. For example, imagine a file called alert_utils.dart with the following content:

export 'src/snackbar_utils.dart';
export 'src/dialog_utils.dart';

The result is an alert_utils library collecting elements from both the snackbar_utils and the dialog_utils libraries.

Wrapping up the definition of Library Packages, you can see its purpose is to define libraries that both types of packages can import and use.

Diagram of the two types of packages