Dart

Dart is an approachable, portable, and productive language for high-quality apps on any platform. Learn more at https://dart.dev.

Announcing Dart 3.7

Marya Belanger
Dart
Published in
6 min readFeb 12, 2025

--

It’s a new year, and time for a new Dart stable release. Welcome to Dart 3.7!

The theme for this release is developer productivity. We’ve made the Dart language more consistent by tweaking how it handles wildcard variables. There’s also a brand new style in the Dart formatter, new quick fixes and lints in the analyzer, and several cool new features on pub.dev. Let’s get into the details!

Announcing Dart 3.7
Announcing Dart 3.7

Macros update

We recently posted updates in the issue tracker, as well as a blog post, stating that we’re stopping work on our experimental macros feature. We’d like to thank the community for being so understanding of this unfortunate outcome.

With this change, however, the team gains back some capacity to invest in other valuable developments. We’re already looking into improvements to build_runner performance, we still expect to launch the augmentations language feature (perhaps in a slightly different form), and we hope to find new and more direct ways for supporting modeling data and handling serialization and deserialization (to and from JSON, for example).

Wildcard variables language feature

Local variables and parameters named _ are now what functional languages call “wildcards”. This means the name is a placeholder and declares no actual variable.

Currently in Dart, it’s common to use _ as the name of a callback parameter if the body of the callback doesn’t actually need to use the argument, like so:

void announceCompletion(Future<void> future) {
future.then((_) { // <--
print('Complete!');
});
}

But, if a callback has multiple parameters that you don’t need to use, you end up naming them _, __, ___, etc., because otherwise the names collide. Now, in Dart 3.7, parameters and local variables named _ don’t actually create a variable, so there is no possibility of name collision. You can use _ for multiple parameters, as in:

void announceFailure(Future<void> future) {
future.onError((_, _) { // <--
print('Error!');
});
}

If you have code that declares a parameter or variable named _ and uses it, that code will no longer work in Dart 3.7. For example:

var [1, 2, 3].map((_) {
return _.toString();
// ^ Error! Reference to unknown variable.
});

You’ll have to rename the parameter or local variable in this situation. This language change only applies to parameters and local variables (not top-level variables or members), so you can do this renaming without breaking your library’s public API.

Wildcard variables are a small feature that make the language more consistent. Variables named _ in patterns have always behaved this way:

var [_, _, third, _, _] = [1, 2, 3, 4, 5];
print(third); // Prints "3".

Now parameters and local variables behave the same way.

New formatting style in the Dart formatter

Dart 3.7 includes a re-written Dart formatter (dart format) with a new formatting style. The new style looks similar to the style you get when you add trailing commas to argument lists, except now the formatter will add and remove those commas for you. For example:

// Old style:
void writeArgumentList(
Token leftBracket, List<AstNode> elements, Token rightBracket) {
writeList(
leftBracket: leftBracket,
elements,
rightBracket: rightBracket,
allowBlockArgument: true);
}

// New style:
void writeArgumentList(
Token leftBracket,
List<AstNode> elements,
Token rightBracket,
) {
writeList(
leftBracket: leftBracket,
elements,
rightBracket: rightBracket,
allowBlockArgument: true,
);
}

This is a large change both to the tool, the output it produces, and how it behaves. To make the transition as smooth as possible, the formatting style you get depends on the language version of the code you’re formatting. If the language version is 3.6 or earlier, the code is formatted with the old style. If it’s 3.7 or later, it gets the new style.

When you upgrade your package to use Dart 3.7 by bumping the SDK constraint in your package’s pubspec (and running dart pub get!), you are opting in to the new formatting style.

To determine the language version of each file it formats, dart format looks for a package_config.json. This means that you need to run dart pub get before formatting code in your package. If you have format checks in your continuous integration server, make sure it runs dart pub get, too.

We don’t intend to support both styles indefinitely. At some point in the future, when most of the ecosystem is on 3.7 or later, support for the old style will be removed.

The new style includes some long-requested features:

  • Project-wide page width configuration. You can now configure your preferred formatting page width on a project-wide basis in your analysis_options.yaml file, like so:
    formatter:
page_width: 123
  • Opting out a region of code from formatting. You can use a pair of special marker comments to opt a region of code out of automated formatting:
    main() {
// dart format off
no + formatting + here;
// dart format on
}

There is one breaking change as well. The formatter no longer supports dart format --fix. Instead, use dart fix to apply all the fixes that dart format could, and more.

You can find more details in the CHANGELOG and FAQ.

Updated quick fixes and new lints in the Dart analyzer

We’re always actively improving Dart to boost developer productivity, and that means improving the analyzer with new lints, quick fixes, and assists in Dart 3.7. One notable addition is the unnecessary_underscores lint, which supports the new wildcard variable feature.

Among the wide range of new quick fixes and assists Dart 3.7 includes are fixes for common issues like missing await keywords, incorrect import prefixes, and violations of lint rules like cascade_invocations. There are also handy assists for refactoring code, such as converting else blocks to else if and wrapping Flutter widgets with Expanded or Flexible.

You can find more details about all of these, and much more, in the full list of analyzer changes.

Moving forward on the Dart web platform

A year ago, we introduced new libraries and packages for interoperating with JavaScript and browser APIs from Dart. Going forward, the primary JavaScript library is dart:js_interop. For browser APIs, use package:web.

As part of our continued effort to move the Dart and Flutter ecosystems to WebAssembly-compatible APIs, we are deprecating the associated legacy APIs in the Dart SDK. Seven Dart SDK libraries are deprecated in the Dart 3.7 release:

  • dart:html
  • dart:indexed_db
  • dart:js
  • dart:js_util
  • dart:web_audio
  • dart:web_gl

We plan to remove these libraries at the end of 2025. You can learn about their replacements on the JavaScript interoperability page.

New productivity features on the pub.dev package site

In December we launched download counts for packages on pub.dev. These show monthly downloads along with a small chart showing weekly downloads over time.

Today, we are extending that with support for viewing download counts per package version. It’s now possible to get an indication of how many consumers of a package have upgraded to the latest version (or just the latest major version). These insights are meant to help package authors gauge the value of back-porting fixes to older major versions of a package.

Weekly downloads chart
Weekly downloads chart

Dark mode for pub.dev

Dark mode for pub.dev has long been a popular request, and as of today it’s now possible to toggle pub.dev to dark mode. This toggle affects both package pages and package API documentation hosted on pub.dev.

Dark mode for pub.dev

Topics for pub.dev

Last year, we launched support for topics on pub.dev. You can add topics to your pubspec.yaml, and if you see related topics that should be merged you can propose canonicalization with a pull request.

Users browsing pub.dev can click on topics to browse related packages. We previously introduced the ability to search for topics on pub.dev, using search keywords (like “topic:widget”), but finding these keywords has not always been easy. So, we’ve launched an IDE-like auto-completer for search keywords on pub.dev. You can trigger it by pressing ctrl+space, or automatically trigger it when you type a matching prefix like “topic:” or “license:”.

Topics search keywords

Wrap up

That’s all we have today for Dart 3.7. As always, please let us know what you think! And don’t forget to check out the blog post for today’s Flutter 3.29 release as well. See you next time!

--

--

Dart
Dart

Published in Dart

Dart is an approachable, portable, and productive language for high-quality apps on any platform. Learn more at https://dart.dev.

Marya Belanger
Marya Belanger

Responses (14)