# Style guide for Flutter repo

## Summary

Optimize for readability. Write detailed documentation.
Make error messages useful.
Never use timeouts or timers.
Avoid `is`, `print`, `part of`, `extension` and `_`.

## Introduction

This document contains some high-level philosophy and policy decisions for the Flutter
project, and a description of specific style issues for some parts of the codebase.

The style portion describes the preferred style for code written as part of the Flutter
project (the framework itself and all our sample code). Flutter application developers
are welcome to follow this style as well, but this is by no means required. Flutter
will work regardless of what style is used to author applications that use it.

The engine repository uses [other style guides for non-Dart code](https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style). The language-neutral sections in this document still apply to engine code, however.


## Overview

This document describes our approach to designing and programming Flutter,
from high-level architectural principles all the way to indentation rules.
These are our norms, written down so that we can easily convey our shared
understanding with new team members.

The primary goal of these style guidelines is to improve code readability so
that everyone, whether reading the code for the first time or
maintaining it for years, can quickly determine what the code does.
Secondary goals are to design systems that are simple; to increase the
likelihood of catching bugs quickly; and to avoid arguments when there are
disagreements over subjective matters.

For anything not covered by this document, check the
[Dart style guide](https://www.dartlang.org/guides/language/effective-dart/)
for more advice. That document is focused primarily on Dart-specific
conventions, while this document is more about Flutter conventions.

In some cases (for example, line wrapping around `if` statements) the
Dart style guide differs from the Flutter guide. For Flutter project code,
the Flutter guide governs. The differences are a result of slightly different
priorities. The Flutter guide is designed for making code highly readable
even to people who have never seen the code before and are new to Dart, as
the Flutter framework code will be read millions of times more than it is written.
The Dart guide, on the other hand, is designed to provide a more balanced approach
that assumes that the writing of the code will be a bigger proportion of the
interactions with the code, and that the reader is more experienced with Dart.
(The `dart format` tool uses the Dart guide, so we do not use it in the
flutter/flutter and flutter/engine repositories. However, we do recommend its
use in general.)

### A word on designing APIs

Designing an API is an art. Like all forms of art, one learns by practicing. The best way to get good at designing APIs is to spend a decade or more designing them, while working closely with people who are using your APIs. Ideally, one would first do this in very controlled situations, with small numbers of developers using one's APIs, before graduating to writing APIs that will be used by hundreds of thousands or even millions of developers.

In the absence of one's own experience, one can attempt to rely on the experience of others. The biggest problem with this is that sometimes explaining why an API isn't optimal is a very difficult and subtle task, and sometimes the reasoning doesn't sound convincing unless you already have a lot of experience designing them.

Because of this, and contrary to almost any other situation in engineering, when you are receiving feedback about API design from an experienced API designer, they will sometimes seem unhappy without quite being able to articulate why. When this happens, seriously consider that your API should be scrapped and a new solution found.

This requires a different and equally important skill when designing APIs: not getting attached to one's creations. One should try many wildly different APIs, and then attempt to write code that uses those APIs, to see how they work. Throw away APIs that feel frustrating, that lead to buggy code, or that other people don't like. If it isn't elegant, it's usually better to try again than to forge ahead.

An API is for life, not just for the one PR you are working on.


## Philosophy

### Lazy programming

Write what you need and no more, but when you write it, do it right.

Avoid implementing features you don't need. You can't design a feature
without knowing what the constraints are. Implementing features "for
completeness" results in unused code that is expensive to maintain,
learn about, document, test, etc.

When you do implement a feature, implement it the right way. Avoid
workarounds. Workarounds merely kick the problem further down the
road, but at a higher cost: someone will have to relearn the problem,
figure out the workaround and how to dismantle it (and all the places
that now use it), _and_ implement the feature. It's much better to
take longer to fix a problem properly, than to be the one who fixes
everything quickly but in a way that will require cleaning up later.

You may hear team members say "embrace the [yak shave](http://www.catb.org/jargon/html/Y/yak-shaving.html)!". This is
an encouragement to [take on the larger effort necessary](https://www.youtube.com/watch?v=AbSehcT19u0) to perform a
proper fix for a problem rather than just applying a band-aid.


### Write Test, Find Bug

When you fix a bug, first write a test that fails, then fix the bug
and verify the test passes.

When you implement a new feature, write tests for it. (See also: [Running and writing tests](./testing/Running-and-writing-tests.md), and the section on writing tests below.)

Check the code coverage
to make sure every line of your new code is tested. See also: [Test coverage for package:flutter](./testing/Test-coverage-for-package-flutter.md).

If something isn't tested, it is very likely to regress or to get "optimized away".
If you want your code to remain in the codebase, you should make sure to test it.

Don't submit code with the promise to "write tests later".  Just take the
time to write the tests properly and completely in the first place.


### Avoid duplicating state

There should be no objects that represent live state that reflect
some state from another source, since they are expensive to maintain.
(The Web's `HTMLCollection` object is an example of such an object.)
In other words, **keep only one source of truth**, and **don't replicate
live state**.


### Getters feel faster than methods

Property getters should be efficient (e.g. just returning a cached
value, or an O(1) table lookup). If an operation is inefficient, it
should be a method instead. (Looking at the Web again: we would have
`document.getForms()`, not `document.forms`, since it walks the entire tree).

Similarly, a getter that returns a Future should not kick-off the work
represented by the future, since getters appear idempotent and side-effect free.
Instead, the work should be started from a method or constructor, and the
getter should just return the preexisting Future.


### No synchronous slow work

There should be no APIs that require synchronously completing an
expensive operation (e.g. computing a full app layout outside of the
layout phase). Expensive work should be asynchronous.


### Layers

We use a layered framework design, where each layer addresses a
narrowly scoped problem and is then used by the next layer to solve
a bigger problem. This is true both at a high level (widgets relies
on rendering relies on painting) and at the level of individual
classes and methods (e.g. `Text` uses `RichText` and `DefaultTextStyle`).

Convenience APIs belong at the layer above the one they are simplifying.


### Avoid interleaving multiple concepts together

Each API should be self-contained and should not know about other features.
Interleaving concepts leads to _complexity_.

For example:

- Many Widgets take a `child`. Widgets should be entirely agnostic about the type
of that child. Don't use `is` or similar checks to act differently based on the
type of the child.

- Render objects each solve a single problem. Rather than having a render object
handle both clipping and opacity, we have one render object for clipping, and one
for opacity.

- In general, prefer immutable objects over mutable data. Immutable objects can
be passed around safely without any risk that a downstream consumer will change
the data. (Sometimes, in Flutter, we pretend that some objects are immutable even
when they technically are not: for example, widget child lists are often technically
implemented by mutable `List` instances, but the framework will never modify them
and in fact cannot handle the user modifying them.) Immutable data also turns out
to make animations much simpler through _lerping_.


### Avoid secret (or global) state

A function should operate only on its arguments and, if it is an instance
method, data stored on its object. This makes the code significantly easier
to understand.

For example, when reading this code:

```dart
// ... imports something that defines foo and bar ...

void main() {
  foo(1);
  bar(2);
}
```

...the reader should be confident that nothing in the call to `foo` could affect anything in the
call to `bar`.

This usually means structuring APIs so that they either take all relevant inputs as arguments, or so
that they are based on objects that are created with the relevant input, and can then be called to
operate on those inputs.

This significantly aids in making code testable and in making code understandable and debuggable.
When code operates on secret global state, it's much harder to reason about.


### Prefer general APIs, but use dedicated APIs where there is a reason

For example, having dedicated APIs for performance reasons is fine. If one
specific operation, say clipping a rounded rectangle, is expensive
using the general API but could be implemented more efficiently
using a dedicated API, then that is where we would create a dedicated API.


### Avoid the lowest common denominator

It is common for SDKs that target multiple platforms (or meta-platforms that
themselves run on multiple platforms, like the Web) to provide APIs that
work on all their target platforms. Unfortunately, this usually means that
features that are unique to one platform or another are unavailable.

For Flutter, we want to avoid this by explicitly aiming to be the best way
to develop for each platform individually. Our ability to be used cross-
platform is secondary to our ability to be used on each platform. For example,
[TextInputAction](https://master-api.flutter.dev/flutter/services/TextInputAction-class.html)
has values that only make sense on some platforms. Similarly, our platform
channel mechanism is designed to allow separate extensions to be created on
each platform.


### Avoid APIs that encourage bad practices

For example, don't provide APIs that walk entire trees, or that encourage
O(N^2) algorithms, or that encourage sequential long-lived operations where
the operations could be run concurrently.

In particular:

  - String manipulation to generate data or code that will subsequently
    be interpreted or parsed is a bad practice as it leads to code
    injection vulnerabilities.

  - If an operation is expensive, that expense should be represented
    in the API (e.g. by returning a `Future` or a `Stream`).  Avoid
    providing APIs that hide the expense of tasks.


### Avoid exposing API cliffs

Convenience APIs that wrap some aspect of a service from one environment
for exposure in another environment (for example, exposing an Android API
in Dart), should expose/wrap the complete API, so that there's no cognitive cliff
when interacting with that service (where you are fine using the exposed
API up to a point, but beyond that have to learn all about the underlying
service).


### Avoid exposing API oceans

APIs that wrap underlying services but prevent the underlying API from
being directly accessed (e.g. how `dart:ui` exposes Skia) should carefully
expose only the best parts of the underlying API. This may require refactoring
features so that they are more usable. It may mean avoiding exposing
convenience features that abstract over expensive operations unless there's a
distinct performance gain from doing so. A smaller API surface is easier
to understand.

For example, this is why `dart:ui` doesn't expose `Path.fromSVG()`: we checked,
and it is just as fast to do that work directly in Dart, so there is no benefit
to exposing it. That way, we avoid the costs (bigger API surfaces are more
expensive to maintain, document, and test, and put a compatibility burden on
the underlying API).


### Avoid heuristics and magic

Predictable APIs that the developer feels gives them control are generally preferred
over APIs that mostly do the right thing but don't give the developer any way to adjust
the results.

Predictability is reassuring.


### Solve real problems by literally solving a real problem

Where possible, especially for new features, you should partner with a real
customer who wants that feature and is willing to help you test it. Only by
actually using a feature in the real world can we truly be confident that a
feature is ready for prime time.

Listen to their feedback, too. If your first customer is saying that your
feature doesn't actually solve their use case completely, don't dismiss their
concerns as esoteric. Often, what seems like the problem when you start a
project turns out to be a trivial concern compared to the real issues faced
by real developers.


### Get early feedback when designing new APIs

If you're designing a new API or a new feature, consider [writing a design doc](Design-Documents.md).
Then, get feedback from the relevant people, e.g. send it to `flutter-dev` or
post it on the [relevant chat channel](Chat.md#existing-channels).


### Start designing APIs from the closest point to the developer

When we create a new feature that requires a change to the entire stack, it's tempting to design the lowest-level API first, since that's the closest to the "interesting" code (the "business end" of the feature, where we actually do the work). However, that then forces the higher level APIs to be designed against the lower-level API, which may or may not be a good fit, and eventually the top-level API, which developers will primarily be using, may be forced to be a tortured and twisted mess (either in implementation or in terms of the exposed API). It may even be that the final API doesn't fit how people think about the problem or solve their actual issues, but instead merely exposes the lowest-level feature almost verbatim.

Instead, always design the top-level API first. Consider what the most ergonomic API would be at the level that most developers will be interacting with it. Then, once that API is cleanly designed and usability-tested, build the lower levels so that the higher level can be layered atop.

Concretely, this means designing the API at the `material` or `widgets` layer first, then the API in the `rendering`, `scheduler`, or `services` layer, then the relevant binding, then the `dart:ui` API or the message channel protocol, then the internal engine API or the plugin API. (The details may vary from case to case.)


### Only log actionable messages to the console

If the logs contain messages that the user can safely ignore, then they will do so, and eventually their logs
will be so chatty and verbose that they will miss the critical messages. Therefore, only log actual errors and
actionable warnings (warnings that can always be dealt with and fixed).

Never log "informational" messages by default. It is possible that it may be useful to have messages on certain topics while debugging those topics. To deal with that, have debug flags you can enable that enable extra logging for particular topics. For example, setting `debugPrintLayouts` to true enables logging of layouts.

This also applies to our unopt builds. It's annoying for other people on the team to have to wade through messages that aren't directly relevant to their work. Rely on feature flags, not verbosity levels, when deciding
to output messages. The one exception to this is reporting useful milestones; for example, the `flutter` tool in
verbose mode (`-v`) reports meaningful steps that it is executing because those are almost always useful.


### Error messages should be useful

Every time you find the need to report an error (e.g. throwing an exception in the framework, handling some bad state in the engine, reporting a syntax error in the Dart compiler, etc), consider how you can make this the most useful and helpful error message ever.

Put yourself in the shoes of whoever sees that error message. Why did they see it? What can we do to help them? They are at a crossroads, having seen your error message: they can either get frustrated and hate Flutter, or they can feel thankful that the error helped them resolve an actual issue. **Every error message is an opportunity to make someone love our product.**

### Template values should set developers up for success

Template defaults should focus on providing the best developer experience. Templates should help developers understand the code, be easy to run now and support in the future. Help developers by picking dependencies that are broadly used and/or broadly supported and by leaving [comments that are helpful](#leave-breadcrumbs-in-the-comments).

See flutter create's templates for an example.

## Policies

This section defines some policies that we have decided to honor. In the absence of a very specific policy in this section, the general philosophies in the section above are controlling.

### Plugin compatibility

We guarantee that a plugin published with a version equal to or greater than 1.0.0 will require no more recent a version of Flutter than the latest stable release at the time that the plugin was released. (Plugins may support older versions too, but that is not guaranteed.)

### Workarounds

We are willing to implement temporary (one week or less) workarounds (e.g. `//ignore` hacks) if it helps a high profile developer or prolific contributor with a painful transition. Please contact @Hixie (ian@hixie.ch) if you need to make use of this option.

### Avoid abandonware

Code that is no longer maintained should be deleted or archived in some way that clearly indicates
that it is no longer maintained.

For example, we delete rather than commenting out code. Commented-out code will bitrot too fast to be
useful, and will confuse people maintaining the code.

Similarly, all our repositories should have an owner that does regular triage of incoming issues and PRs,
and fixes known issues. Repositories where nobody is doing triage at least monthly, preferably more often,
should be deleted, hidden, or otherwise archived.

### Widget libraries follow the latest OEM behavior

For our material and cupertino libraries, we generally implement the latest behavior unless doing so
would be a seriously disruptive breaking change. For example, we use the latest stylings for iOS
switch controls, but when Material Design introduced a whole new type of button, we created a new
widget for that rather than updating the existing buttons to have the new style.

### Code that is not copyrighted "The Flutter Authors"

All code in all Flutter repositories must be contributed by developers who have signed [the Google CLA](https://cla.developers.google.com/), and must be licensed using our normal BSD license with a copyright referencing "The Flutter Authors", except if it is "third party code".

"Third party code" that is not part of a Dart package must be in a subdirectory of a `third_party` directory at the root of the relevant repository, and the subdirectory in question must contain a `LICENSE` file that details the license covering that code and a `README` describing the provenance of that code.

"Third party code" that is part of a Dart package and is not Dart code must be in a subdirectory of a `third_party` directory at the root of the package, and the subdirectory in question must contain a `LICENSE` file that details the license covering that code and a `README` describing the provenance of that code. The license must then also be duplicated into the package's `LICENSE` file using the syntax described in the [LicenseRegistry](https://master-api.flutter.dev/flutter/foundation/LicenseRegistry-class.html) API docs.

"Third party code" that is part of a Dart package and is Dart code must be in a subdirectory of the package's `lib/src/third_party` directory, and the subdirectory in question must contain a `LICENSE` file that details the license covering that code and a `README` describing the provenance of that code. The license must then also be duplicated into the package's `LICENSE` file using the syntax described in the [LicenseRegistry](https://master-api.flutter.dev/flutter/foundation/LicenseRegistry-class.html) API docs.

All licenses included in this manner must have been reviewed and determined to be legally acceptable licenses.

All such "third party code" must either be a fork for which we take full responsibility, or there must be an automated rolling mechanism that keeps the code up to date when the upstream source changes.

In general it is _strongly_ recommended that we avoid any such code unless strictly necessary. In particular, we aim for all code in the flutter/flutter repository to be [single-licensed](../about/Why-we-have-a-separate-engine-repo.md#licensing), which is why it does not contain any "third party code" at all.


## Documentation (dartdocs, javadocs, etc)

We use "dartdoc" for our Dart documentation, and similar technologies for the documentation
of our APIs in other languages, such as ObjectiveC and Java. All public members in Flutter
libraries should have a documentation.

In general, follow the
[Dart documentation guide](https://www.dartlang.org/effective-dart/documentation/#doc-comments)
except where that would contradict this page.

### Answer your own questions straight away

When working on Flutter, if you find yourself asking a question about
our systems, please place whatever answer you subsequently discover
into the documentation in the same place where you first looked for
the answer. That way, the documentation will consist of answers to real
questions, where people would look to find them. Do this right away;
it's fine if your otherwise-unrelated PR has a bunch of documentation
fixes in it to answer questions you had while you were working on your PR.

We try to avoid reliance on "oral tradition". It should be possible
for anyone to begin contributing without having had to learn all the
secrets from existing team members. To that end, all processes should
be documented (typically on the wiki), code should be self-explanatory
or commented, and conventions should be written down, e.g. in our style
guide.

There is one exception: it's better to _not_ document something in our API
docs than to document it poorly. This is because if you don't document it,
it still appears on our list of things to document. Feel free to remove
documentation that violates our rules below (especially the next one),
so as to make it reappear on the list.


### Avoid useless documentation

If someone could have written the same documentation without knowing
anything about the class other than its name, then it's useless.

Avoid checking in such documentation, because it is no better than no
documentation but will prevent us from noticing that the identifier is
not actually documented.

Example (from [`CircleAvatar`](http://docs.flutter.io/flutter/material/CircleAvatar-class.html)):

```dart
// BAD:

/// The background color.
final Color backgroundColor;

/// Half the diameter of the circle.
final double radius;


// GOOD:

/// The color with which to fill the circle.
///
/// Changing the background color will cause the avatar to animate to the new color.
final Color backgroundColor;

/// The size of the avatar.
///
/// Changing the radius will cause the avatar to animate to the new size.
final double radius;
```

### Writing prompts for good documentation

If you are having trouble coming up with useful documentation, here are some prompts that might help you write more detailed prose:

 * If someone is looking at this documentation, it means that they have a question which they couldn't answer by guesswork or by looking at the code. What could that question be? Try to answer all questions you can come up with.

 * If you were telling someone about this property, what might they want to know that they couldn't guess? For example, are there edge cases that aren't intuitive?

 * Consider the type of the property or arguments. Are there cases that are outside the normal range that should be discussed? e.g. negative numbers, non-integer values, transparent colors, empty arrays, infinities, NaN, null? Discuss any that are non-trivial.

 * Does this member interact with any others? For example, can it only be non-null if another is null? Will this member only have any effect if another has a particular range of values? Will this member affect whether another member has any effect, or what effect another member has?

 * Does this member have a similar name or purpose to another, such that we should point to that one, and from that one to this one? Use the `See also:` pattern.

 * Are there timing considerations? Any potential race conditions?

 * Are there lifecycle considerations? For example, who owns the object that this property is set to? Who should `dispose()` it, if that's relevant?

 * What is the contract for this property/method? Can it be called at any time? Are there limits on what values are valid? If it's a `final` property set from a constructor, does the constructor have any limits on what the property can be set to? If this is a constructor, are any of the arguments not nullable?

 * If there are `Future` values involved, what are the guarantees around those? Consider whether they can complete with an error, whether they can never complete at all, what happens if the underlying operation is canceled, and so forth.


### Introduce terms as if every piece of documentation is the first the reader has ever seen

It's easy to assume that the reader has some basic knowledge of Dart or Flutter when writing API documentation.

Unfortunately, the reality is that everyone starts knowing nothing, and we do not control where they will begin their journey.

For this reason, avoid using terms without first defining them, unless you are linking to more fundamental documentation that defines that term without reference to the API you are documenting.

For example, a fancy widget in the Material library can refer to the `StatefulWidget` documentation and assume that the reader either knows about the `StatefulWidget` class, or can learn about it by following the link and then later returning to the documentation for the fancy widget. However, the documentation for the `StatefulWidget` class should avoid assuming that the reader knows what a `State` class is, and should avoid deferring to it for its definition, because `State` could is likely to defer back to `StatefulWidget` and the reader would be stuck in a loop unable to grasp the basic principles. This is the documentation equivalent of a bootstrapping problem.

Another way to express this is that API documentation should follow a similar layering philosophy as code. The goal of documentation is not just to act as a refresher for experts, but to act as a tutorial for new developers.


### Avoid empty prose

It's easy to use more words than necessary. Avoid doing so
where possible, even if the result is somewhat terse.

```dart
// BAD:

/// Note: It is important to be aware of the fact that in the
/// absence of an explicit value, this property defaults to 2.

// GOOD:

/// Defaults to 2.
```

In particular, avoid saying "Note:", or starting a sentence with "Note that". It adds nothing.


### Leave breadcrumbs in the comments

This is especially important for documentation at the level of classes.

If a class is constructed using a builder of some sort, or can be
obtained via some mechanism other than merely calling the constructor,
then include this information in the documentation for the class.

If a class is typically used by passing it to a particular API, then
include that information in the class documentation also.

If a method is the main mechanism used to obtain a particular object,
or is the main way to consume a particular object, then mention that
in the method's description.

Typedefs should mention at least one place where the signature is used.

These rules result in a chain of breadcrumbs that a reader can follow
to get from any class or method that they might think is relevant to
their task all the way up to the class or method they actually need.

Example:

```dart
// GOOD:

/// An object representing a sequence of recorded graphical operations.
///
/// To create a [Picture], use a [PictureRecorder].
///
/// A [Picture] can be placed in a [Scene] using a [SceneBuilder], via
/// the [SceneBuilder.addPicture] method. A [Picture] can also be
/// drawn into a [Canvas], using the [Canvas.drawPicture] method.
abstract class Picture ...
```

You can also use "See also" links, as in:

```dart
/// See also:
///
/// * [FooBar], which is another way to peel oranges.
/// * [Baz], which quuxes the wibble.
```

Each line should end with a period. Prefer "which..." rather than parentheticals on such lines.
There should be a blank line between "See also:" and the first item in the bulleted list.


### Refactor the code when the documentation would be incomprehensible

If writing the documentation proves to be difficult because the API is
convoluted, then rewrite the API rather than trying to document it.


### Canonical terminology

The documentation should use consistent terminology:

 * _method_ - a member of a class that is a non-anonymous closure
 * _function_ - a callable non-anonymous closure that isn't a member of a class
 * _parameter_ - a variable defined in a closure signature and possibly used in the closure body.
 * _argument_ - the value passed to a closure when calling it.

Prefer the term "call" to the term "invoke" when talking about jumping to a closure.

Prefer the term "member variable" to the term "instance variable" when talking about variables associated with a specific object.

Typedef dartdocs should usually start with the phrase "Signature for...".


### Use correct grammar

Avoid starting a sentence with a lowercase letter.

```dart
// BAD

/// [foo] must not be null.

// GOOD

/// The [foo] argument must not be null.
```

Similarly, end all sentences with a period.


### Use the passive voice; recommend, do not require; never say things are simple

Never use "you" or "we". Avoid the imperative voice. Avoid value judgements.

Rather than telling someone to do something, use "Consider", as in "`To obtain the foo, consider using [bar].`".

In general, you don't know who is reading the documentation or why. Someone could have inherited a terrible codebase and be reading our documentation to find out how to fix it; by saying "you should not do X" or "avoid Y" or "if you want Z", you will put the reader in a defensive state of mind when they find code that contradicts the documentation (after all, they inherited this codebase, who are we to say that they're doing it wrong, it's not their fault).

For similar reasons, never use the word "simply", or say that the reader need "just" do something, or otherwise imply that the task is easy.
By definition, if they are looking at the documentation, they are not finding it easy.


### Provide sample code

Sample code helps developers learn your API quickly. Writing sample code also helps you think through how your API is going to be used by app developers.

Sample code should go in a documentation comment that typically begins with `/// {@tool dartpad}`, and ends with `/// {@end-tool}`, with the example source and corresponding tests placed in a file under [the API examples directory](https://github.com/flutter/flutter/blob/main/examples/api). This will then be checked by automated tools, and formatted for display on the API documentation web site [api.flutter.dev](https://api.flutter.dev). For details on how to write sample code, see [the API example documentation](https://github.com/flutter/flutter/blob/main/examples/api/README.md#authoring).

#### Provide full application samples.

Our UX research has shown that developers prefer to see examples that are in the context of an entire app. So, whenever it makes sense, provide an example that can be presented as part of an entire application instead of just a snippet that uses the `{@tool snippet}` or &#96;&#96;&#96;dart ... &#96;&#96;&#96; indicators.

An application sample can be created using the `{@tool dartpad}` ... `{@end-tool}` or `{@tool sample}` ... `{@end-tool}` dartdoc indicators. See [here](https://github.com/flutter/flutter/blob/main/examples/api/README.md#authoring) for more details about writing these kinds of examples.

Dartpad examples (those using the dartdoc `{@tool dartpad}` indicator) will be presented on the [API documentation website](https://api.flutter.dev) as an in-page executable and editable example. This allows developers to interact with the example right there on the page, and is the preferred form of example. Here is [one such example](https://api.flutter.dev/flutter/widgets/AnimatedSwitcher-class.html#widgets.AnimatedSwitcher.1).

For examples that don't make sense in a web page (for example, code that interacts with a particular platform feature), application examples (using the dartdoc `{@tool sample}` indicator) are preferred, and will be presented on the API documentation website along with information about how to instantiate the example as an application that can be run.

Supported IDEs viewing the Flutter source code using the Flutter plugin also offer the option of creating a new project with either kind of example.

### Provide illustrations, diagrams or screenshots

For any widget that draws pixels on the screen, showing how it looks like in its API doc helps developers decide if the widget is useful and learn how to customize it. All illustrations should be easily reproducible, e.g. by running a Flutter app or a script.

Examples:

* A diagram for the AppBar widget

![AppBar diagram](https://flutter.github.io/assets-for-api-docs/assets/material/app_bar.png)


* A screenshot for the Card widget

![Card screenshot](https://user-images.githubusercontent.com/348942/28338544-2c3681b8-6bbe-11e7-967d-fcd7c830bf53.png)

When creating diagrams, make sure to provide alternative text [as described in the HTML specification](https://html.spec.whatwg.org/multipage/images.html#alt).


### Link to Widget of the Week videos

Link to a widget's Flutter Widget of the Week video if it has one:

```dart
/// {@youtube 560 315 https://www.youtube.com/watch?v=<id>}
```

The first two arguments are the video's width and height. These should be `560` and `315` respectively.


### Clearly mark deprecated APIs

We have conventions around deprecation. See the [Tree Hygiene](Tree-hygiene.md#deprecations) page for more details.


### Use `///` for public-quality private documentation

In general, private code can and should also be documented. If that documentation is of good enough
quality that we could include it verbatim when making the class public (i.e. it satisfies all the
style guidelines above), then you can use `///` for those docs, even though they're private.

Documentation of private APIs that is not of sufficient quality should only use `//`. That way, if
we ever make the corresponding class public, those documentation comments will be flagged as missing,
and we will know to examine them more carefully.

Feel free to be conservative in what you consider "sufficient quality". It's ok to use `//` even if
you have multiple paragraphs of documentation; that's a sign that we should carefully rereview the
documentation when making the code public.

### Dartdoc templates and macros

Dartdoc supports creating templates that can be reused in other parts of the code. They are defined
like so:

```dart
/// {@template <id>}
/// ...
/// {@endtemplate}
```

and used via:

```dart
/// {@macro <id>}
```

The `<id>` should be a unique identifier that is of the form `flutter.library.Class.member[.optionalDescription]`.

For example:

```
// GOOD:
/// {@template flutter.rendering.Layer.findAnnotations.aboutAnnotations}
/// Annotations are great!
/// {@endtemplate

// BAD:
/// {@template the_stuff!}
/// This is some great stuff!
/// {@endtemplate}
```

The `optionalDescription` component of the identifier is only necessary if there is more than one
template defined in one Dartdoc block. If a symbol is not part of a library, or not part of a class, then
just omit those parts from the ID.

### Dartdoc-specific requirements

The first paragraph of any dartdoc section must be a short self-contained sentence that explains the purpose
and meaning of the item being documented. Subsequent paragraphs then must elaborate. Avoid having the first paragraph have multiple sentences. (This is because the first paragraph gets extracted and used in tables of
contents, etc, and so has to be able to stand alone and not take up a lot of room.)

When referencing a parameter, use backticks. However, when referencing a parameter that also corresponds to a property, use square brackets instead. (This contradicts the Dart style guide, which says to use square brackets for both. We do this because of [dartdoc issue 1486](https://github.com/dart-lang/dartdoc/issues/1486). Currently, there's no way to unambiguously reference a parameter. We want to avoid cases where a parameter that happens to be named the same as a property despite having no relationship to that property gets linked to the property.)

```dart
// GOOD

  /// Creates a foobar, which allows a baz to quux the bar.
  ///
  /// The [bar] argument must not be null.
  ///
  /// The `baz` argument must be greater than zero.
  Foo({ this.bar, int baz }) : assert(bar != null), assert(baz > 0);
```

Avoid using terms like "above" or "below" to reference one dartdoc section from another. Dartdoc sections are often shown alone on a Web page, the full context of the class is not present.


## Coding patterns and catching bugs early

### Use asserts liberally to detect contract violations and verify invariants

`assert()` allows us to be diligent about correctness without paying a
performance penalty in release mode, because Dart only evaluates asserts in
debug mode.

It should be used to verify contracts and invariants are being met as we expect.
Asserts do not _enforce_ contracts, since they do not run at all in release builds.
They should be used in cases where it should be impossible for the condition
to be false without there being a bug somewhere in the code.

The following example is from `box.dart`:

```dart
abstract class RenderBox extends RenderObject {
  // ...

  double getDistanceToBaseline(TextBaseline baseline, {bool onlyReal: false}) {
    // simple asserts:
    assert(!needsLayout);
    assert(!_debugDoingBaseline);
    // more complicated asserts:
    assert(() {
      final RenderObject parent = this.parent;
      if (owner.debugDoingLayout) {
        return (RenderObject.debugActiveLayout == parent) && parent.debugDoingThisLayout;
      }
      if (owner.debugDoingPaint) {
        return ((RenderObject.debugActivePaint == parent) && parent.debugDoingThisPaint)
            || ((RenderObject.debugActivePaint == this)   && debugDoingThisPaint);
      }
      assert(parent == this.parent);
      return false;
    });
    // ...
    return 0.0;
  }

  // ...
}
```

### Prefer specialized functions, methods and constructors

Use the most relevant constructor or method, when there are multiple
options.

Example:

```dart
// BAD:
const EdgeInsets.TRBL(0.0, 8.0, 0.0, 8.0);

// GOOD:
const EdgeInsets.symmetric(horizontal: 8.0);
```


### Minimize the visibility scope of constants

Prefer using a local const or a static const in a relevant class than using a
global constant.

As a general rule, when you have a lot of constants, wrap them in a
class. For examples of this, see
[lib/src/material/colors.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/src/material/colors.dart).


### Avoid using `if` chains or `?:` or `==` with enum values

Use `switch` with no `default` case if you are examining an enum, since the analyzer will warn you if you missed any of the values when you use `switch`. The `default` case should be avoided so that the analyzer will complain if a value is missing. Unused values can be grouped together with a single `break` or `return` as appropriate.

Avoid using `if` chains, `? ... : ...`, or, in general, any expressions involving enums.


### Avoid using `var` and `dynamic`

All variables and arguments are typed; avoid `dynamic` or `Object` in
any case where you could figure out the actual type. Always specialize
generic types where possible. Explicitly type all list and map
literals. Give types to all parameters, even in closures and even if you
don't use the parameter.

This achieves two purposes: it verifies that the type that the compiler
would infer matches the type you expect, and it makes the code self-documenting
in the case where the type is not obvious (e.g. when calling anything other
than a constructor).

Always avoid `var` and `dynamic`. If the type is unknown, prefer using
`Object` (or `Object?`) and casting, as using `dynamic` disables all
static checking.


### Avoid using `library` and `part of`.

Prefer that each library be self-contained. Only name a `library` if you are documenting it (see the
documentation section).

We avoid using `part of` because that feature makes it very hard to reason about how private a private
really is, and tends to encourage "spaghetti" code (where distant components refer to each other) rather
than "lasagna" code (where each section of the code is cleanly layered and separable).


### Avoid using `extension`.

Extension methods are confusing to document and discover. To an end developer,
they appear no different than the built-in API of the class, and discovering
the documentation and implementation of an extension is more challenging than
for class members.

Prefer instead adding methods directly to relevant classes. If that is not
possible, create a method that clearly identifies what object(s) it works with
and is part of.

(A rare exception can be made for extensions that provide temporary workarounds
when deprecating features. In those cases, however, the extensions and all their
members must be deprecated in the PR that adds them, and they must be removed
in accordance with our deprecation policy.)


### Avoid using `FutureOr<T>`

The `FutureOr` type is a Dart-internal type used to explain certain aspects of the `Future` API. In public APIs, avoid the temptation to create APIs that are both synchronous and asynchronous by returning this type, as it usually only results in the API being more confusing and less type safe.

In certain extreme cases where the API absolutely needs to be asynchronous but a synchronous "escape hatch" is needed for performance, consider using `SynchronousFuture` (but be aware that this still suffers from many of the same risks of making the API only subtle and complicated). This is used, for example, when loading images in the Flutter framework.

You may use `FutureOr` to accept a callback that may or may not return a `Future`.


### Avoid using `Expando`

Generally speaking, `Expando` objects are a sign of an architectural problem. Carefully consider whether your usage is actually necessary. When your classes have clear documented ownership rules, there is usually a better solution.

Expando objects tend to invite code that is hard to understand because one cannot simply follow references to find all the dependencies.


### Avoid using `@visibleForTesting`

The [`@visibleForTesting`](https://api.flutter.dev/flutter/meta/visibleForTesting-constant.html) annotation marks a public API so that developers that have not disabled the `invalid_use_of_visible_for_testing_member` analyzer error get a warning when they use this API outside of a `test` directory.

This means that the API has to be treated as being public (nothing prevents a developer from using the API even in non-test code), meaning it must be designed to be a public API, it must be documented, it must be tested, etc. At which point, there's really no reason not to just make it a public API. If anything, the use of `@visibleForTesting` becomes merely a crutch to convince ourselves that it's ok that we're making something public that we should really not have made public.

So rather than rely on `@visibleForTesting`, consider designing your APIs so that they are directly testable using the public API, without exposing any sensitive internals.

(One exception is combining `@visibleForTesting` with `@protected`. The `@protected` annotation marks a member as one that is intended for subclasses, so it is already a public API and considered as such. The `@visibleForTesting` annotation in that case merely enables the member to be called directly in tests without having to create a fake subclass and without having to add `//ignore` pragmas.)


### Never check if a port is available before using it, never add timeouts, and other race conditions.

If you look for an available port, then try to open it, it's extremely likely that several times a week some other code will open that port between your check and when you open the port, and that will cause a failure.

> Instead, have the code that opens the port pick an available port and return it, rather than being given a (supposedly) available port.

If you have a timeout, then it's very likely that several times a week some other code will happen to run while your timeout is running, and your "really conservative" timeout will trigger even though it would have worked fine if the timeout was one second longer, and that will cause a failure.

> Instead, have the code that would time out just display a message saying that things are unexpectedly taking a long time, so that someone interactively using the tool can see that something is fishy, but an automated system won't be affected.

Race conditions like this are the primary cause of flaky tests, which waste everyone's time.

Similarly, avoid delays or sleeps that are intended to coincide with how long something takes. You may think that waiting two seconds is fine because it normally takes 10ms, but several times a week your 10ms task will actually take 2045ms and your test will fail because waiting two seconds wasn't long enough.

> Instead, wait for a triggering event.


### Avoid mysterious and magical numbers that lack a clear derivation

Numbers in tests and elsewhere should be clearly understandable. When the provenance of a number is not obvious,
consider either leaving the expression or adding a clear comment (bonus points for leaving a diagram).

```dart
// BAD
expect(rect.left, 4.24264068712);

// GOOD
expect(rect.left, 3.0 * math.sqrt(2));
```


### Have good hygiene when using temporary directories

Give the directory a unique name that starts with `flutter_` and ends with a period (followed by the autogenerated random string).

For consistency, name the `Directory` object that points to the temporary directory `tempDir`, and create it with `createTempSync` unless you need to do it asynchronously (e.g. to show progress while it's being created).

Always clean up the directory when it is no longer needed. In tests, use the `tryToDelete` convenience function to delete the directory. (We use `tryToDelete` because on Windows it's common to get "access denied" errors when deleting temporary directories. We have no idea why; if you can figure it out then that could simplify a lot of code!)


### Perform dirty checks in setters

Dirty checks are processes to determine whether a changed values have been synchronized with the rest of the app.

When defining mutable properties that mark a class dirty when set, use
the following pattern:

```dart
/// Documentation here (don't wait for a later commit).
TheType get theProperty => _theProperty;
TheType _theProperty;
void set theProperty(TheType value) {
  assert(value != null);
  if (_theProperty == value) {
    return;
  }
  _theProperty = value;
  markNeedsWhatever(); // the method to mark the object dirty
}
```

The argument is called 'value' for ease of copy-and-paste reuse of
this pattern. If for some reason you don't want to use 'value', use
'newProperty' (where 'Property' is the property name).

Start the method with any asserts you need to validate the value.

Don't do anything _else_ in setters, other than marking the object as dirty and updating internal state.
Getters and setters should not have significant side-effects. For example, setting a property whose value
is a callback should not result in that callback being invoked. Setting a property whose value is an object
of some sort should not result in any of that object's methods being called.


### Common boilerplates for `operator ==` and `hashCode`

We have many classes that override `operator ==` and `hashCode` ("value classes"). To keep the code consistent,
we use the following style for these methods:

```dart
  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is Foo
        && other.bar == bar
        && other.baz == baz
        && other.quux == quux;
  }

  @override
  int get hashCode => Object.hash(bar, baz, quux);
```

For objects with a lot of properties, consider adding the following at the top of the `operator ==`:

```dart
    if (identical(other, this)) {
      return true;
    }
```

(We don't yet use this _exact_ style everywhere, so feel free to update code you come across that isn't yet using it.)

In general, consider carefully whether overriding `operator ==` is a good idea. It can be expensive, especially
if the properties it compares are themselves comparable with a custom `operator ==`. If you do override equality,
you should use `@immutable` on the class hierarchy in question.


### Override `toString`

Use [`Diagnosticable`](https://api.flutter.dev/flutter/foundation/Diagnosticable-mixin.html) (rather than directly overriding `toString`) on all but the most trivial classes. That allows us to inspect the object from [devtools](https://pub.dartlang.org/packages/devtools) and IDEs.

For trivial classes, override `toString` as follows, to aid in debugging:

```dart
  @override
  String toString() => '${objectRuntimeType(this, 'NameOfObject')}($bar, $baz, $quux)';
```

...but even then, consider using `Diagnosticable` instead.  Avoid using `$runtimeType`, since it adds a non-trivial cost even in release and profile mode. The `objectRuntimeType` method handles this for you, falling back to a supplied constant string when asserts are disabled.


### Be explicit about `dispose()` and the object lifecycle

Even though Dart is garbage collected, having a defined object lifecycle and explicit ownership model (describing in the API documentation who is allowed to mutate the object, for instance) is important to avoid subtle bugs and confusing designs.

If your class has a clear "end of life", for example, provide a `dispose()` method to clean up references such as listeners that would otherwise prevent some objects from getting garbage collected. For example, consider a widget that has a subscription on a global broadcast stream (that might have other listeners). That subscription will keep the widget from getting garbage collected until the stream itself goes away (which, for a global stream, might never happen).

In general, pretending that Dart does not have garbage collection is likely to lead to less confusing and buggy code, because it forces you to think about the implications of object ownership and lifecycles.


### Test APIs belong in the test frameworks

Mechanisms that exist for test purposes do not belong in the core libraries, they belong in test harnesses. This keeps the cost of the main library down in production and avoids the risk that people might abuse test APIs.


### Immutable classes should not have hidden state

Immutable classes (those with `const` constructors) should not have hidden state. For example, they should not use private statics or Expandos. If they are stateful, then they should not be `const`.


### Avoid `sync*`/`async*`

Using generator functions (`sync*`/`async*`) can be a powerful improvement when callers will
actually lazily evaluate the iterable and each iteration is expensive _or_ there are a very
large number of iterations.

It should not be used in place of building and returning a `List`, particularly for trivial methods
that only yield a small number of members or when callers will evaluate the whole collection
anyway. It should also be avoided in very large functions.

It incurs runtime overhead in maintaining and using an iterator, and space overhead for the compiler
to actually desugar the generator into something that uses an iterator class.

## Writing tests

### Make each test entirely self-contained

Embrace code duplication in tests. It makes it easier to make new tests by copying and pasting them and
tweaking a few things.

Avoid using `setUp`, `tearDown`, and similar features, as well as test-global variables or other state
shared between tests. They make writing tests easier but make maintaining them, debugging them, and
refactoring code much harder. (These are commonly used in Flutter's codebase today, but that is almost
always a mistake. When you are editing a file that uses those features, aim to reduce the number of
tests using them while you're there.)

Specifically, we are trying to avoid shared state, which could persist across tests, and non-local
side-effects, which would prevent being able to move a test to another file without breaking the test.
(It's fine to factor out code into functions that are called by tests, so long as the functions don't
have side-effects that might change how other tests run.)


### Prefer more test files, avoid long test files

Avoid adding tests to files that already have more than one or two hundred lines of code. It's easier
to understand a test file when it has only a few related tests, rather than when it has an entire test
suite. (It also makes developing the tests faster because you can run the test file faster.)


### Avoid using `pumpAndSettle`

As per the API docs for [pumpAndSettle](https://main-api.flutter.dev/flutter/flutter_test/WidgetController/pumpAndSettle.html), prefer using explicit [`pump`](https://main-api.flutter.dev/flutter/flutter_test/WidgetController/pump.html) calls rather than `pumpAndSettle`.

Using `pumpAndSettle`, especially without checking its return value, makes it very easy for bugs to sneak in where we trigger animations across multiple frames instead of immediately. It is almost always the case that a call to `pumpAndSettle` is more strictly correctly written as two `pump` calls, one to trigger the animations and one (with a duration) to jump to the point after the animations.


## Naming

### Begin global constant names with prefix "k"

Examples:

```dart
const double kParagraphSpacing = 1.5;
const String kSaveButtonTitle = 'Save';
```

However, where possible avoid global constants. Rather than `kDefaultButtonColor`, consider `Button.defaultColor`. If necessary, consider creating an `abstract final class` to hold relevant constants.


### Avoid abbreviations

Unless the abbreviation is more recognizable than the expansion (e.g. XML, HTTP, JSON), expand abbreviations
when selecting a name for an identifier. In general, avoid one-character names unless one character is idiomatic
(for example, prefer `index` over `i`, but prefer `x` over `horizontalPosition`).


### Avoid anonymous parameter names

Provide full type information and names even for parameters that are otherwise unused. This makes it easier for
people reading the code to tell what is actually going on (e.g. what is being ignored). For example:

```dart
  onTapDown: (TapDownDetails details) { print('hello!'); }, // GOOD
  onTapUp: (_) { print('good bye'); }, // BAD
```


### Naming rules for typedefs and function variables

When naming callbacks, use `FooCallback` for the typedef, `onFoo` for
the callback argument or property, and `handleFoo` for the method
that is called. If `Foo` is a verb, prefer the present tense to the
past tense (e.g. `onTap` instead of `onTapped`).

If you have a callback with arguments but you want to ignore the
arguments, give the type and names of the arguments anyway. That way,
if someone copies and pastes your code, they will not have to look up
what the arguments are.

Never call a method `onFoo`. If a property is called `onFoo` it must be
a function type. (For all values of "Foo".)

Prefer using `typedef`s to declare callbacks. Typedefs benefit from having
documentation on the type itself and make it easier to read and find
common callsites for the signature.

### Spell words in identifiers and comments correctly

Our primary source of truth for spelling is the
[Material Design Specification](https://material.google.com/).
Our secondary source of truth is dictionaries.

Avoid "cute" spellings. For example, 'colors', not 'colorz'.

Prefer US English spellings. For example, 'colorize', not 'colourise', and 'canceled', not 'cancelled'.

Prefer compound words over "cute" spellings to avoid conflicts with reserved words. For example, 'classIdentifier', not 'klass'.


### Capitalize identifiers consistent with their spelling

In general, we use [Dart's recommendations](https://dart.dev/guides/language/effective-dart/style#identifiers) for naming identifiers. Please consider the following additional guidelines:

If a word is correctly spelled (according to our sources of truth as described in the previous section) as a single word, then it should not have any inner capitalization or spaces.

For examples, prefer `toolbar`, `scrollbar`, but `appBar` ('app bar' in documentation), `tabBar` ('tab bar' in documentation).

Similarly, prefer `offstage` rather than `offStage`.

Avoid using class names with `iOS` when possible. The capitalization of `iOS` is supposed to be exactly that, but that doesn't work well with camelCase and even less with UpperCamelCase; use alternatives like "Cupertino" or "UIKit" instead when possible. If you really really must use "iOS" in an identifier, capitalize it to `IOS`. Whether or not [the two-letter exception](https://dart.dev/guides/language/effective-dart/style#do-capitalize-acronyms-and-abbreviations-longer-than-two-letters-like-words) applies to "iOS" is debatable, but `IOS` is consistent with Dart APIs, and the alternatives (`IOs`, `Ios`) are even more jarring. (Previous versions of this guide incorrectly indicated that `Ios` was the correct capitalization when necessary; this form should not be used in new code.)


### Avoid double negatives in APIs

Name your boolean variables in positive ways, such as "enabled" or "visible", even if the default value is true.

This is because, when you have a property or argument named "disabled" or "hidden", it leads to code such as `input.disabled = false` or `widget.hidden = false` when you're trying to enable or show the widget, which is very confusing.


### Prefer naming the argument to a setter `value`

Unless this would cause other problems, use `value` for the name of a setter's argument. This makes it easier to copy/paste the setter later.


### Qualify variables and methods used only for debugging

If you have variables or methods (or even classes!) that are only used in debug mode,
prefix their names with `debug` or `_debug` (or, for classes, `_Debug`).

Do not use debugging variables or methods (or classes) in production code.


### Avoid naming undocumented libraries

In other words, do not use the `library` keyword, unless it is a
documented top-level library intended to be imported by users.

### Avoid "new/old" modifiers in code

The definition of "New" changes as code grows and time passes. If the code
needed a replacement version the odds of needing another replacement in the
future is higher. Instead find a name that represents the idea being used
or replaced.


## Comments

### Avoid checking in comments that ask questions

Find the answers to the questions, or describe the confusion, including
references to where you found answers.

If commenting on a workaround due to a bug, also leave a link to the issue and
a TODO to clean it up when the bug is fixed.

Example:

```dart
// BAD:

// What should this be?

// This is a workaround.


// GOOD:

// According to this specification, this should be 2.0, but according to that
// specification, it should be 3.0. We split the difference and went with
// 2.5, because we didn't know what else to do.

// TODO(username): Converting color to RGB because class Color doesn't support
//                 hex yet. See http://link/to/a/bug/123
```

TODOs should include the string TODO in all caps, followed by the GitHub username of
the person with the best _context_ about the problem referenced by the TODO in
parentheses. A TODO is not a commitment that the person referenced will fix the
problem, it is intended to be the person with enough context to explain the problem.
Thus, when you create a TODO, it is almost always your username that is given.

Including an issue link in a TODO description is required.

_(See also [#37519](https://github.com/flutter/flutter/issues/37519),
which tracks a proposal to change the syntax of TODOs to not include usernames.)_

### Comment all `// ignores`

Sometimes, it is necessary to write code that the analyzer is unhappy with.

If you find yourself in this situation, consider how you got there. Is the analyzer actually correct but you
don't want to admit it? Think about how you could refactor your code so that the analyzer is happy. If such a
refactor would make the code better, do it. (It might be a lot of work... embrace the yak shave.)

If you are really really sure that you have no choice but to silence the analyzer, use `// ignore: `. The ignore
directive should be on the same line as the analyzer warning.

If the ignore is temporary (e.g. a workaround for a bug in the compiler or analyzer, or a workaround for some known problem in Flutter that you cannot fix), then add a link to the relevant bug, as follows:

```dart
  foo(); // ignore: lint_code, https://link.to.bug/goes/here
```

If the ignore directive is permanent, e.g. because one of our lints has some unavoidable false positives and in this case violating the lint is definitely better than all other options, then add a comment explaining why:

```dart
  foo(); // ignore: lint_code, sadly there is no choice but to do
  // this because we need to twiddle the quux and the bar is zorgle.
```

### Comment all test skips

On very rare occasions it may be necessary to skip a test. To do that, use the `skip` argument.
Any time you use the `skip` argument, file an issue describing why it is skipped and
include a link to that issue in the code.


### Comment empty closures to `setState`

Generally the closure passed to `setState` should include all the code that changes the state. Sometimes this is not possible because the state changed elsewhere and the `setState` is called in response. In those cases, include a comment in the `setState` closure that explains what the state is that changed.

```dart
  setState(() {
    // The animation ticked. We use the animation's value in the build method.
  });
```


## Formatting

These guidelines have no technical effect, but they are still important purely
for consistency and readability reasons.

We do not yet use `dartfmt` (except in flutter/packages).
Flutter code tends to use patterns that
the standard Dart formatter does not handle well. We are
[working with Dart team](https://github.com/flutter/flutter/issues/2025) to make `dartfmt` aware of these patterns.


### In defense of the extra work that hand-formatting entails

Flutter code might eventually be read by hundreds of thousands of people each day.
Code that is easier to read and understand saves these people time. Saving each
person even a second each day translates into hours or even _days_ of saved time
each day. The extra time spent by people contributing to Flutter directly translates
into real savings for our developers, which translates to real benefits to our end
users as our developers learn the framework faster.


### Constructors come first in a class

The default (unnamed) constructor should come first, then the named
constructors. They should come before anything else (including, e.g., constants or static methods).

This helps readers determine whether the class has a default implied constructor or not at a glance. If it was possible for a constructor to be anywhere in the class, then the reader would have to examine every line of the class to determine whether or not there was an implicit constructor or not.


### Order other class members in a way that makes sense

The methods, properties, and other members of a class should be in an order that
will help readers understand how the class works.

If there's a clear lifecycle, then the order in which methods get invoked would be useful, for example an  `initState` method coming before `dispose`. This helps readers because the code is in chronological order, so
they can see variables get initialized before they are used, for instance. Fields should come before the methods that manipulate them, if they are specific to a particular group of methods.

> For example, RenderObject groups all the layout fields and layout
> methods together, then all the paint fields and paint methods, because layout
> happens before paint.

If no particular order is obvious, then the following order is suggested, with blank lines between each one:

1. Constructors, with the default constructor first.
2. Constants of the same type as the class.
3. Static methods that return the same type as the class.
4. Final fields that are set from the constructor.
5. Other static methods.
6. Static properties and constants.
7. Members for mutable properties, without new lines separating the members of a property, each property in the order:
    - getter
    - private field
    - setter
8. Read-only properties (other than `hashCode`).
9. Operators (other than `==`).
10. Methods (other than `toString` and `build`).
11. The `build` method, for `Widget` and `State` classes.
12. `operator ==`, `hashCode`, `toString`, and diagnostics-related methods, in that order.

Be consistent in the order of members. If a constructor lists multiple
fields, then those fields should be declared in the same order, and
any code that operates on all of them should operate on them in the
same order (unless the order matters).


### Constructor syntax

If you call `super()` in your initializer list, put a space between the
constructor arguments' closing parenthesis and the colon. If there's
other things in the initializer list, align the `super()` call with the
other arguments. Don't call `super` if you have no arguments to pass up
to the superclass.

```dart
// one-line constructor example
class ConstantTween<T> extends Tween<T> {
  ConstantTween(T value) : super(begin: value, end: value);

  // ...
}

// fully expanded constructor example
class ConstantTween<T> extends Tween<T> {
  ConstantTween(
    T value,
  ) : super(
        begin: value,
        end: value,
      );

  // ...
}
```


### Prefer a maximum line length of 80 characters

Aim for a maximum line length of roughly 80 characters, but prefer going over if breaking the
line would make it less readable, or if it would make the line less consistent
with other nearby lines. Prefer avoiding line breaks after assignment operators.

```dart
// BAD (breaks after assignment operator and still goes over 80 chars)
final int a = 1;
final int b = 2;
final int c =
    a.very.very.very.very.very.long.expression.that.returns.three.eventually().but.is.very.long();
final int d = 4;
final int e = 5;

// BETTER (consistent lines, not much longer than the earlier example)
final int a = 1;
final int b = 2;
final int c = a.very.very.very.very.very.long.expression.that.returns.three.eventually().but.is.very.long();
final int d = 4;
final int e = 5;
```

```dart
// BAD (breaks after assignment operator)
final List<FooBarBaz> _members =
  <FooBarBaz>[const Quux(), const Qaax(), const Qeex()];

// BETTER (only slightly goes over 80 chars)
final List<FooBarBaz> _members = <FooBarBaz>[const Quux(), const Qaax(), const Qeex()];

// BETTER STILL (fits in 80 chars)
final List<FooBarBaz> _members = <FooBarBaz>[
  const Quux(),
  const Qaax(),
  const Qeex(),
];
```


### Indent multi-line argument and parameter lists by 2 characters

When breaking an argument list into multiple lines, indent the
arguments two characters from the previous line.

Example:

```dart
Foo f = Foo(
  bar: 1.0,
  quux: 2.0,
);
```

When breaking a parameter list into multiple lines, do the same.


### If you have a newline after some opening punctuation, match it on the closing punctuation.

And vice versa.

Example:

```dart
// BAD:
  foo(
    bar, baz);
  foo(
    bar,
    baz);
  foo(bar,
    baz
  );

// GOOD:
  foo(bar, baz);
  foo(
    bar,
    baz,
  );
```

### Use a trailing comma for arguments, parameters, and list items, but only if they each have their own line.

Example:
```dart
List<int> myList = [
  1,
  2,
];
myList = <int>[3, 4];

foo1(
  bar,
  baz,
);
foo2(bar, baz);
```

If one of the items is a multi-line callback, collection literal,
or switch expression, it can be added without a trailing comma.

```dart
// GOOD:
foo(
  bar,
  baz,
  switch (value) {
    true  => ScrollDirection.forward,
    false => ScrollDirection.reverse,
    null  => ScrollDirection.idle,
  },
);

// also GOOD:
foo(bar, baz, switch (value) {
  true  => ScrollDirection.forward,
  false => ScrollDirection.reverse,
  null  => ScrollDirection.idle,
});

// The same applies to collection literals and callbacks:
foo(<String>[
  'list item 1',
  'list item 2',
  'list item 3',
]);

Future.delayed(Durations.short1, () {
  if (mounted && _shouldOpenDrawer) {
    _drawerController.forward();
  }
});
```

Whether to put things all on one line or whether to have one line per item is an aesthetic choice. We prefer whatever ends up being most readable. Typically this means that when everything would fit on one line, put it all on one line, otherwise, split it one item to a line.

However, there are exceptions. For example, if there are six back-to-back lists and all but one of them need multiple lines, then one would not want to have the single case that does fit on one line use a different style than the others.

```dart
  // BAD (because the second list is unnecessarily and confusingly different than the others):
  List<FooBarBaz> myLongList1 = <FooBarBaz>[
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
  ];
  List<Quux> myLongList2 = <Quux>[ Quux(1), Quux(2) ];
  List<FooBarBaz> myLongList3 = <FooBarBaz>[
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
  ];

  // GOOD (code is easy to scan):
  List<FooBarBaz> myLongList1 = <FooBarBaz>[
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
  ];
  List<Quux> myLongList2 = <Quux>[
    Quux(1),
    Quux(2),
  ];
  List<FooBarBaz> myLongList3 = <FooBarBaz>[
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
    FooBarBaz(one: firstArgument, two: secondArgument, three: thirdArgument),
  ];
```


### Consider using `=>` for short functions and methods

But only use `=>` when everything, including the function declaration, fits
on a single line.

Example:

```dart
// BAD:
String capitalize(String s) =>
  '${s[0].toUpperCase()}${s.substring(1)}';

// GOOD:
String capitalize(String s) => '${s[0].toUpperCase()}${s.substring(1)}';

String capitalize(String s) {
  return '${s[0].toUpperCase()}${s.substring(1)}';
}
```

### Use `=>` for getters and callbacks that just return literals or switch expressions

```dart
// GOOD:
List<Color> get favorites => <Color>[
  const Color(0xFF80FFFF),
  const Color(0xFF00FFF0),
  const Color(0xFF4000FF),
  _mysteryColor(),
];

// GOOD:
bool get isForwardOrCompleted => switch (status) {
  AnimationStatus.forward || AnimationStatus.completed => true,
  AnimationStatus.reverse || AnimationStatus.dismissed => false,
};
```

It's important to use discretion, since there are cases where a function body
is easier to visually parse:

```dart
// OKAY, but the code is more dense than it could be:
String? get validated => switch(input[_inputIndex]?.trim()) {
  final String value when value.isNotEmpty => value,
  _ => null,
}

// BETTER (more verbose, but also more readable):
String? get validated {
  final String? value = input[_inputIndex]?.trim();

  if (value != null && value.isNotEmpty) {
    return value;
  }
  return null;
}
```

If your code is passing an inline closure containing only a `return` statement,
you can instead use the `=>` form.\
When doing this, the closing `]`, `}`, or `)` bracket will have the same
indentation as the line where the callback starts.

For example:

```dart
    // GOOD, but slightly more verbose than necessary since it doesn't use =>
    @override
    Widget build(BuildContext context) {
      return PopupMenuButton<String>(
        onSelected: (String value) { print('Selected: $value'); },
        itemBuilder: (BuildContext context) {
          return <PopupMenuItem<String>>[
            PopupMenuItem<String>(
              value: 'Friends',
              child: MenuItemWithIcon(Icons.people, 'Friends', '5 new'),
            ),
            PopupMenuItem<String>(
              value: 'Events',
              child: MenuItemWithIcon(Icons.event, 'Events', '12 upcoming'),
            ),
          ];
        }
      );
    }

    // GOOD, does use =>, slightly briefer
    @override
    Widget build(BuildContext context) {
      return PopupMenuButton<String>(
        onSelected: (String value) { print('Selected: $value'); },
        itemBuilder: (BuildContext context) => <PopupMenuItem<String>>[
          PopupMenuItem<String>(
            value: 'Friends',
            child: MenuItemWithIcon(Icons.people, 'Friends', '5 new'),
          ),
          PopupMenuItem<String>(
            value: 'Events',
            child: MenuItemWithIcon(Icons.event, 'Events', '12 upcoming'),
          ),
        ]
      );
    }
```

The important part is that the closing punctuation lines up with the start
of the line that has the opening punctuation, so that you can easily determine
what's going on by just scanning the indentation on the left edge.


### Prefer single line for short collection-if and collection-for

If the code fits in a single line don't split it.

For example:

```dart
// BAD
final List<String> args = <String>[
  'test',
  if (useFlutterTestFormatter) '-rjson'
  else '-rcompact',
  '-j1',
  if (!hasColor)
    '--no-color',
  for (final String opt in others)
    opt,
];

// GOOD
final List<String> args = <String>[
  'test',
  if (useFlutterTestFormatter) '-rjson' else '-rcompact',
  '-j1',
  if (!hasColor) '--no-color',
  for (final String opt in others) opt,
];
```

Otherwise indent with 2 spaces

```dart
// GOOD
final List<String> args = <String>[
  'test',
  if (useFlutterTestFormatter)
    '-rjson.very.very.very.very.very.very.very.very.long'
  else
    '-rcompact.very.very.very.very.very.very.very.very.long',
  '-j1',
  if (!hasColor)
    '--no-color.very.very.very.very.very.very.very.very.long',
  for (final String opt in others)
    methodVeryVeryVeryVeryVeryVeryVeryVeryVeryLong(opt),
];
```

### Put spread inside collection-if or collection-for on the same line

Spreads inside collection-if or collection-for are used to insert several elements. It's easier to read to have spread on the line of `if`, `else`, or `for`.

```dart
// BAD
final List<String> args = <String>[
  'test',
  if (condA)
    ...<String>[
      'b',
      'c',
    ]
  else
    '-rcompact',
  for (final String opt in others)
    ...<String>[
      m1(opt),
      m2(opt),
    ],
];

// GOOD
final List<String> args = <String>[
  'test',
  if (condA) ...<String>[
    'b',
    'c',
  ] else
    '-rcompact',
  for (final String opt in others) ...<String>[
    m1(opt),
    m2(opt),
  ],
];
```


### Use braces for long functions and methods

Use a block (with braces) when a body would wrap onto more than one line (as opposed to using `=>`; the cases where you can use `=>` are discussed in the previous two guidelines).


### Align expressions

Where possible, subexpressions on different lines should be aligned, to make the structure of the expression easier. When doing this with a `return` statement chaining `||` or `&&` operators, consider putting the operators on the left hand side instead of the right hand side.

```dart
// BAD:
if (foo.foo.foo + bar.bar.bar * baz - foo.foo.foo * 2 +
    bar.bar.bar * 2 * baz > foo.foo.foo) {
  // ...
}

// GOOD (notice how it makes it obvious that this code can be simplified):
if (foo.foo.foo     + bar.bar.bar     * baz -
    foo.foo.foo * 2 + bar.bar.bar * 2 * baz   > foo.foo.foo) {
  // ...
}
// After simplification, it fits on one line anyway:
if (bar.bar.bar * 3 * baz > foo.foo.foo * 2) {
  // ...
}
```

```dart
// BAD:
return foo.x == x &&
    foo.y == y &&
    foo.z == z;

// GOOD:
return foo.x == x &&
       foo.y == y &&
       foo.z == z;

// ALSO GOOD:
return foo.x == x
    && foo.y == y
    && foo.z == z;
```

### Prefer `+=` over `++`

We generally slightly prefer `+=` over `++`.

In some languages/compilers postfix `++` is an antipattern because of performance reasons, and so it's easier to just avoid it in general.

Because of the former, some people will use the prefix `++`, but this leads to statements that lead with punctuation, which is aesthetically displeasing.

In general, mutating variables as part of larger expressions leads to confusion about the order of operations, and entwines the increment with another calculation.

Using `++` does not make it obvious that the underlying variable is actually being mutated, whereas `+=` more clearly does (it's an assignment with an `=` sign).

Finally, `+=` is more convenient when changing the increment to a number other than 1.

### Use double literals for double constants

To make it clearer when something is a double or an integer, even if the number is a round number, include a decimal point in double literals. For example, if a function `foo` takes a double, write `foo(1.0)` rather than `foo(1)` because the latter makes it look like the function takes an integer.


## Conventions

### Expectations around potential crashes in the engine

The engine should never crash in an uncontrolled fashion.

In unopt mode, the engine C++ code should have asserts that check for contract violations.

In opt debug mode, the `dart:ui` code should have asserts that check for contract violations. These asserts should have messages that are detailed and useful, if they are not self-explanatory.

In opt release mode, the exact behavior can be arbitrary so long as it is defined and non-vulnerable for every input. For example, a contract violation could be checked in Dart, with an exception thrown for invalid data; but equally valid would be for the C++ code to return early when faced with invalid data. The idea is to optimize for speed in the case where the data is valid.

For practical purposes we don't currently check for out-of-memory errors. Ideally we would.


### Features we expect every widget to implement

Now that the Flutter framework is mature, we expect every new widget to implement all of the following:

- full accessibility, so that on both Android and iOS the widget works with the native accessibility tools.
- full localization with default translations for all our default languages.
- full support for both right-to-left and left-to-right layouts, driven by the ambient Directionality.
- full support for text scaling up to at least 3.0x.
- documentation for every member; see the section above for writing prompts to write documentation.
- good performance even when used with large amounts of user data.
- a complete lifecycle contract with no resource leaks (documented, if it differs from usual widgets).
- tests for all the above as well as all the unique functionality of the widget itself.

It's the job of the programmer to provide these before submitting a PR.

It's the job of the reviewer to check that all these are present when reviewing a PR.


### Use of streams in Flutter framework code

In general we avoid the use of `Stream` classes in Flutter framework code (and `dart:ui`). Streams in general are fine and we encourage people to use them. However, they have some disadvantages and we prefer to keep them out of the framework for this reason. For example:

* Streams have a heavy API. For example, they can be synchronous or asynchronous, broadcast or single-client, and they can be paused and resumed. It is non-trivial to determine the right semantics for a particular stream when it will be used in all the ways framework code could be used, and it is non-trivial to fully implement the semantics correctly.

* Streams don't have a "current value" accessor, which makes them difficult to use in `build` methods.

* The APIs for manipulating streams are non-trivial (e.g. transformers).

We generally prefer `Listenable` subclasses (e.g. `ValueNotifier` or `ChangeNotifier`).

In the specific case of exposing a value from `dart:ui` via a callback, we expect the bindings in the framework to register a single listener and then provide a mechanism to fan the notification to multiple listeners. Sometimes this is a rather involved process (e.g. the `SchedulerBinding` exists almost entirely for the purpose of doing this for `onBeginFrame`/`onDrawFrame`, and the `GesturesBinding` exists exclusively for the purpose of doing this for pointer events). Sometimes it's simpler (e.g. propagating changes to life cycle events).


## Packages

### Structure

As per normal Dart conventions, a package should have a single import
that reexports all of its API.

> For example,
> [rendering.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/rendering.dart)
> exports all of lib/src/rendering/*.dart

If a package uses, as part of its exposed API, types that it imports
from a lower layer, it should reexport those types.

> For example,
> [material.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/material.dart)
> reexports everything from
> [widgets.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/widgets.dart).
> Similarly, the latter
> [reexports](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/src/widgets/basic.dart)
> many types from
> [rendering.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/rendering.dart),
> such as `BoxConstraints`, that it uses in its API. On the other
> hand, it does not reexport, say, `RenderProxyBox`, since that is not
> part of the widgets API.

Flutter packages should not have "private" APIs other than those that are
prefixed with underscores. Every file in a Flutter package should be exported.
("Private" files can still be imported so they are still actually public APIs;
by not exporting them explicitly we are tricking ourselves into thinking of
them as private APIs which may lead to poor design.)

When developing new features in Flutter packages, one should follow the philosophy:

> Only expose the APIs that are necessities to the features.

Since the private classes in dart language are file-bound, this may often result in
large file sizes. In Flutter, this is considered to be more preferable than creating
multiple smaller files but exposing intermediate classes that are not needed to use
the features.


### Import conventions

Under `lib/src`, for in-folder import, use relative import. For cross-folder import,
import the entire package with absolute import.

When importing the `rendering.dart` library into higher level libraries,
if you are creating new
`RenderObject` subclasses, import the entire library. If you are only
referencing specific `RenderObject` subclasses, then import the
`rendering.dart` library with a `show` keyword explicitly listing the
types you are importing. This latter approach is generally good for
documenting why exactly you are importing particularly libraries and
can be used more generally when importing large libraries for very
narrow purposes.

By convention, `dart:ui` is imported using `import 'dart:ui' show
...;` for common APIs (this isn't usually necessary because a lower
level will have done it for you), and as `import 'dart:ui' as ui show
...;` for low-level APIs, in both cases listing all the identifiers
being imported. See
[basic_types.dart](https://github.com/flutter/flutter/blob/main/packages/flutter/lib/src/painting/basic_types.dart)
in the `painting` package for details of which identifiers we import
which way. Other packages are usually imported undecorated unless they
have a convention of their own (e.g. `path` is imported `as path`).

The `dart:math` library is always imported `as math`.

### Deciding where to put code

As a general rule, if a feature is entirely self-contained (not requiring low-level integration into the Flutter framework) and is not something with universal appeal, we would encourage that that feature be provided as a package.

We try to be very conservative with what we put in the core framework, because there's a high cost to having anything there. We have to commit to supporting it for years to come, we have to document it, test it, create samples, we have to consider everyone's varied desires which they may have as they use the feature, we have to fix bugs. If there are design problems, we may not find out for a long time but then once we do we then have to figure out how to fix them without breaking downstream code, or we have to migrate all our existing widgets to the new architecture, etc.

Basically, code is expensive. So before we take it, if possible, we like to see if we can prove the code's value. By creating a package, we can see if people use the feature, how they like it, whether it would be useful for the framework, etc, without having to take on the costs.

We have two main kinds of packages that are maintained by the Flutter team, both of which live in [flutter/packages](https://github.com/flutter/packages):

1. Regular packages, which are pure Dart. Packages can also be written and maintained by people outside the Flutter team.

2. Plugin packages, which provide access to platform features and therefore include native code (such as Java or Objective-C) as well as Dart.

You can also consider making an independent package. Packages are published to [pub](https://pub.dartlang.org/).

Often once we have made a package we find that that is actually sufficient to solve the problem that the code sets out to solve, and there ends up being no need to bring it into the framework at all.