Follow the instructions below to get started, and use the end-to-end example for reference.
If you are adding a DevTools extension to an existing Dart package, proceed to the instructions for configuring your extension.
If you are creating a standalone DevTools extension as a new package (i.e. not part of an existing pub package), then you can build your extension in the same package that it will be published with. Since the extension must be built as a Flutter web app, you can use the following flutter create
template:
flutter create --template app --platforms web my_new_tool
Now use the my_new_tool
package to configure your extension in the next step.
In the Dart package that will provide the DevTools extension to users, add a top-level extension
directory:
some_pkg extension/ lib/ ...
Under this directory, create the following structure:
extension devtools/ build/ config.yaml
The config.yaml
file contains metadata that DevTools needs to load the extension.
name: some_pkg issueTracker: <link_to_your_issue_tracker.com> version: 0.0.1 materialIconCodePoint: '0xe0b1'
Copy the config.yaml
file content above and paste it into the config.yaml
file you just created in your package. It is important that you use the exact file name and field names as shown, or else your extension may fail to load in DevTools.
For each key, fill in the appropriate value for your package.
name
: the package name that this DevTools extension belongs to. The value of this field will be used in the extension page title bar. (required)
issueTracker
: the url for your issue tracker. When a user clicks the “Report an issue” link in the DevTools UI, they will be directed to this url. (required)
version
: the version of your DevTools extension. This version number should evolve over time as you ship new features for your extension. The value of this field will be used in the extension page title bar. (required)
materialIconCodePoint
: corresponds to the codepoint value of an icon from material/icons.dart. This icon will be used for the extension’s tab in the top-level DevTools tab bar. (required)
For the most up-to-date documentation on the config.yaml
spec, see extension_config_spec.md
Now it is time to build your extension.
DevTools extensions must be written as Flutter web apps. This is because DevTools embeds extensions in an iFrame to display them dynamically in DevTools.
Only the pre-compiled output of your extension needs to be shipped with your pub package in order for DevTools to load it.
For a standalone extension (an extension that is not being shipped as part of an existing pub package), it is acceptable to include your source code in the same package that the extension is shipped with. This will simplify development, and since users of your package will add a dependency on your package as a dev_dependency
, the size of your package will not affect the user's app size.
my_new_tool extension/ devtools/ build/ ... # pre-compiled output of the Flutter web app under lib/ config.yaml lib/ # source code for your extension Flutter web app src/ ...
To keep the size of your pub package small, we recommend that you develop your DevTools extension outside of your pub package. Here is the recommended package structure:
some_pkg/ # formerly the repository root of your pub package packages/ some_pkg/ # your pub package extension/ devtools/ build/ ... # pre-compiled output of some_pkg_devtools_extension/lib config.yaml some_pkg_devtools_extension/ lib/ # source code for your extension Flutter web app
Create the Flutter web app
From the directory where you want your extension source code to live, run the following command, replacing some_pkg_devtools_extension
with `<your_package_name>_devtools_extension``:
flutter create --template app --platforms web some_pkg_devtools_extension
Add the devtools_extensions
dependency to your Flutter web app.
In pubspec.yaml
, add the following:
devtools_extensions: ^0.0.14
Add the DevToolsExtension
widget at the root of your Fluter web app.
In lib/main.dart
, add the following:
import 'package:devtools_extensions/devtools_extensions.dart'; import 'package:flutter/material.dart'; void main() { runApp(const SomePkgDevToolsExtension()); } class SomePkgDevToolsExtension extends StatelessWidget { const SomePkgDevToolsExtension({super.key}); @override Widget build(BuildContext context) { return const DevToolsExtension( child: Placeholder(), // Build your extension here ); } }
The DevToolsExtension
widget automatically performs all extension initialization required to interact with DevTools. From anywhere in your extension web app, you can access the globals:
extensionManager
: a manager for interacting with DevTools or the extensions frameworkserviceManager
: a manager for interacting with the connected vm service, if presentdtdManager
: a manager for interacting with the Dart Tooling Daemon, if presentUse package:devtools_app_shared for access to service managers, common widgets, DevTools theming, utilities, and more. See devtools_app_shared/example for sample usages.
For debugging purposes, you will likely want to use the “simulated DevTools environment”. This is a simulated environment that allows you to build your extension without having to develop it as an embedded iFrame in DevTools. Running your extension this way will wrap your extension with an environment that simulates the DevTools-to-extension connection. It also gives you access to hot restart and a faster development cycle.
The simulated environment is enabled by an environment parameter use_simulated_environment
. To run your extension web app with this flag enabled, add a configuration to your launch.json
file in VS code:
{ ... "configurations": [ ... { "name": "some_pkg_devtools_extension + simulated environment", "cwd": "packages/some_pkg_devtools_extension", "request": "launch", "type": "dart", "args": [ "--dart-define=use_simulated_environment=true" ], }, ] }
or launch your app from the command line with the added flag:
flutter run -d chrome --dart-define=use_simulated_environment=true
To use a real DevTools environment, you will need to perform a series of setup steps:
Develop your extension to a point where you are ready to test your changes in a real DevTools environment. Build your flutter web app and copy the built assets from your_extension_web_app/build/web
to your pub package's extension/devtools/build
directory.
Use the build_and_copy
command from package:devtools_extensions
to help with this step.
cd your_extension_web_app; flutter pub get; dart run devtools_extensions build_and_copy --source=. --dest=../some_pkg/extension/devtools
To ensure that your extension is setup properly for loading in DevTools, run the validate
command from package:devtools_extensions
. The --package
argument should point to the root of the Dart package that this extension will be published with.
cd your_extension_web_app; flutter pub get; dart run devtools_extensions validate --package=../some_pkg
Prepare and run a test application that depends on your pub package that is providing the extension. You'll need to change the pubspec.yaml
dependency to be a path dependency that points to your local pub package source code. Once you have done this, run pub get
on the test app, and then run the application.
Start DevTools:
dart devtools
from the command line.Connect your test app to DevTools if it is not connected already, and you should see a tab in the DevTools app bar for your extension. The enabled or disabled state of your extension is managed by DevTools, which is exposed from an “Extensions” menu in DevTools, available from the action buttons in the upper right corner of the screen.
In order for a package to provide a DevTools extension to its users, it must be published with the expected content in the your_package/extension/devtools/
directory (see the setup instructions above).
extension/devtools/config.yaml
file exists and is configured per the specifications above.build_and_copy
command provided by package:devtools_extensions
to build your extension and copy the output to the extension/devtools
directory:cd your_extension_web_app; flutter pub get; dart run devtools_extensions build_and_copy --source=. --dest=../some_pkg/extension/devtools
Then publish your package. When running pub publish
, you will see a warning if you do not have the config.yaml
file and a non-empty build
directory as required.
extension/devtools/build/
contents checked into source control?As a package author, the content that you check into your git repository is completely up to you. If you want the contents of extension/devtools/build/
to be git ignored, then you'll just need to ensure that the extension web app is always built and included in extension/devtools/build/
when you publish your package. To do so, add the following to a .pubignore
file in the extension/devtools/
directory:
!build
This will ensure that, even if the extension/devtools/build
directory has been been git ignored, the directory will still be included when publishing the package on pub.
To verify the published extension contents are always up to date, consider adding a tool script to your repo that looks something like this:
publish.sh
pushd your_extension_web_app flutter pub get dart run devtools_extensions build_and_copy --source=. --dest=../your_pub_package/extension/devtools popd pushd your_pub_package flutter pub publish popd
Please join the Flutter Discord server and then check out the #devtools-extension-authors channel to connect with other DevTools extension authors and the DevTools team.
For feature requests or bugs, please file an issue on the DevTools Github repository.