You've successfully subscribed to
Great! Next, complete checkout for full access to
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.
Success! Your billing info is updated.
Billing info update failed.

How to Create a Flutter Library: my_changelog

Paul Halliday
Paul Halliday

Flutter and the Dart ecosystem makes it easy to create, publish and use new libraries. Within our Flutter applications we can pull libraries in from the filesystem, Git, and, making it easy to make new changes during the development/distribution phase.

What will we be making?

You've been tasked with a way to display a CHANGELOG inside of your application. You decide to create a library for this to make it reusable and offer powerful (future) features such as dialog popups, auto-show on version number change, and so on.

Prior to working on the more complex features, you decide to get an early MVP up and running - simply displaying a file from a local asset or parsing Markdown from a String.

Creating a Flutter project

As always, we can go ahead and create a new Flutter project prior to creating our library:

$ flutter create my_app
Run this inside of your terminal! :)

This will serve as a test bed as we'll be loading our library from the filesystem during development. We'll come back to this later on in the tutorial!

Creating a Flutter library

Next up, we can create a new library by opening a new terminal window and typing the following:

$ flutter create --template=package my_changelog

This will create a new library project named my_changelog. Let's open it up inside of our editor:

$ cd my_changelog
$ code .

We should now be able to see the stock Calculator class and the surrounding test file at lib/my_changelog.dart and test/my_changelog_test.dart:

library my_changelog;

/// A Calculator.
class Calculator {
  /// Returns [value] plus 1.
  int addOne(int value) => value + 1;

There's also other key files that'll need to be configured prior to our deployment such as LICENSE and, aside from that, it's a completely bare-bones Dart/Flutter project.

Adding our dependencies

Let's head over to pubspec.yaml and under the dependencies: key, add the flutter_markdown plugin. We'll need this to parse the Markdown content that we'll be passing into our library later on.

NOTE: We don't need to add the Flutter dependency because we generated this with the Flutter SDK
    sdk: flutter
  flutter_markdown: ^0.3.3

Once you've done this, save the file. If your environment doesn't run flutter pub get by default, run this inside of your terminal from within the my_changelog directory.

Creating the ChangeLogScreen

Next up, we'll be making the ChangeLogScreen that we can import inside of our my_app project that we created earlier. Add the following to your lib/my_changelog.dart file:

library my_changelog;

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_markdown/flutter_markdown.dart';

class ChangeLogScreen extends StatelessWidget {
  final Widget title;
  final String markdownData;
  final bool showAppBar;
  final String markdownFilePath;

  final ScrollController scrollController = ScrollController();

    this.showAppBar = true,

  Widget build(BuildContext context) {
    return Scaffold(
      appBar: showAppBar
          ? AppBar(
              title: title ?? Text(""),
              leading: IconButton(
                icon: Icon(Icons.close),
                onPressed: () => Navigator.of(context).pop(),
          : null,
      body: SafeArea(
        child: markdownFilePath != null
            ? FutureBuilder(
                future: rootBundle.loadString(markdownFilePath),
                    (BuildContext context, AsyncSnapshot<String> snapshot) {
                  if (snapshot.hasData) {
                    return Markdown(
                      controller: scrollController,

                  return Center(child: CircularProgressIndicator());
            : Markdown(
                controller: scrollController,
                data: markdownData,

This should hopefully meet our MVP requirement. We're able to currently customise a StatelessWidget which contains a Scaffold that optionally has an AppBar, markdown support for rootBundle (i.e. project assets), text, and so on.

Adding the my_changelog dependency

Now that we have the foundation of our my_changelog library, we can go ahead and view this inside of our my_app project.  Open this up inside of your editor and head on over to pubspec.yaml and edit your dependencies to include the path for my_changelog on your machine:

    sdk: flutter
    path: "../my_changelog"
Once again, you'll need to run flutter pub get if your environment does not automatically fetch packages after changing this file.

We can also use git instead of a local path here:

      url: git://

Using our library

Now that we've got the my_changelog library, we'll be able to use the exported ChangeLogScreen inside of my_app. Head over to lib/main.dart and update your build to use this:

import 'package:flutter/material.dart';
import 'package:my_changelog/my_changelog.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: ChangeLogScreen(
          title: Text("Changelog"),
          markdownData: """
## 1.1 - 22/02/2020
- Fixed an issue where the lorem wouldn't ipsum.
- Stability improvements.
- Security and bug fixes.

## 1.0 - 21/02/2020
- Added a changelog to the application.

We can now start our project using the debugger on either an iOS or Android emulator/device, showing our ChangeLogScreen in action:

Changelog in action!

We could also display this data using the markdownFilePath if we wanted to turn this into it's own file (such as assets/


In this article we created a new Flutter library to accommodate a CHANGELOG or other Markdown data. In the next part of our library series, we'll look at how to publish this on and make this accessible to everyone without needing it locally or using the git URL.


Paul Halliday

👋 Want to see more content? Head over to the YouTube channel:!