Document your dart and Flutter packages

Document your code

When you are working on a package that you want to share with others, either on pub.dev or internally with your team, you should provide documentation for your public API.

Luckily, we have a great example, the Flutter framework has really great documentation with lots of examples, code snippets.

We can make our package just as nice as the Flutter framework by writing our documentation as doc comments.

In order to write such a comment, we should start the comment with ///.

/// This class is an example of what we could achieve with 
/// dart doc comments
class MyAwesomeFeature {
  /// Creates a new instance of [MyAwesomeFeature] that can do
  /// some cool stuff on [title] and [subTitle].
  /// Usage: 
  /// ```dart
  /// MyAwesomeFeautre(
  ///   title: 'Hello',
  ///   subTitle: 'Flutter!',
  /// ).doSomeCoolThings();
  /// ```
  MyAwesomeFeature({
    required this.title,
    this.subTitle,
  });

  /// This will be the title of our feature.
  final String title;

  /// Optional subtitle, to better express ourselves.
  final String? subTitle;

  /// This method is so cool, it works with the [title] and makes it super cool. 
  void doSomeCoolThings() {}
}

We can reference attributes, methods, other classes inside our doc comments, by wrapping them inside [ and ] as you can see in the example above. These references will be converted to links inside the generated documentation. You can reference any class inside your project or even a method of a class.

Generate your documentation

Once we added the comments to our public API, we can generate the documentation. It is an automatic process when you publish it on pub.dev. If we are not working on a public package, we can generate the documentation manually. Before Flutter 2.10 and Dart 2.16, we could use the dartdoc command-line tool. From Dart 2.16, this tool has been moved under the main dart command, so we can invoke it by running dart doc. Unfortunately, in Dart 2.16, and 2.16.1, it has a bug, which may be fixed in the upcoming 2.16.2 release. Until then we can still use dartdoc if we have an earlier version.

cd your_package
dartdoc .

Or when we are building a Flutter package and the tool does not find the Flutter SDK:

FLUTTER_ROOT=/path/to/flutter/sdk dartdoc .

The generated documentation will be in the docs/api directory and it will look something like this.

Screenshot 2022-02-16 at 16.24.14.png

Screenshot 2022-02-16 at 16.25.29.png

Additional options

You have plenty of options to customize the generation. You have to create a dartdoc_options.yaml in the root of your package. Let me highlight some of its features.

Macros, templates

You can define templates and insert them in other places inside your doc comments. For example you can create a template for the author information:

/// {@template author_information}
/// Made by: David Tengeri <@dtengeri>
/// {@endtemplate}

And you can add this to your comments by inserting it as a macro:

/// My Awesome Library
/// {@macro author_information}
/// Details come here

Categories

You can define categories in the dartdoc_options.yaml. These categories can have their own page and they get a link in the left sidebar.

dartdoc:
  categories:
    "My Cool Category":
      markdown: doc/my_cool_category.md

Here, the md file contains the details of your category. You can mark a library, class or field with your category, so they will be listed on the summary page of the category.

/// {@category My Cool Category}
class MyAwesomeFeature {}

You can assign multiple categories to the same item.

Exclude

You can exclude any commented part from the documentation with the help of @nodoc.

/// This feature must not appear in the documentation.
///
/// {@nodoc}
class HiddenFeature {}

Image, animation, etc.

You have plenty of other options to improve your documentation, by adding images, video files, examples and other configurations. You can find all available options on the dartdoc package site.

Code organization

While I was working on some packages, I noticed a pattern in Flutter widgets about how they structure the fields and methods inside a class. After that I tried to stick to this approach as well, so the structure of the code in my packages will be familiar to Flutter devs.

In the widgets in the Flutter SDK, there is a doc comment for each class, which describe the intention of the widgets.

As I saw, the first item in the widget classes is the constructors. Each of them has doc comments, usually with usage examples.

After all constructors and factories come the list of attributes, nicely commented.

Then comes the build() method.

I think you can see the pattern. Since you usually create the widgets and don't call their methods, it is more valuable to have the constructors at the beginning of the class, so you can find how to use them easier.

Resources

You can find the source code of the sample package at github.com/dtengeri/dart_doc_example