How we partnered with VGV to bring a best-in-class tool to the world of Flutter

Flutter hit the scene as a development framework in 2018, created by Google as a way of building visually striking, cross-platform apps with a single codebase. Since then, its adoption has exploded among developers around the world — StackOverflow is even calling it “the most popular cross-platform mobile SDK”.

But the tooling ecosystem built to service Flutter hasn’t necessarily kept up. Observability solutions compatible with Flutter often provide limited support — they don’t always capture the same breadth of data that’s available for native apps. And many available plugins require manually instrumenting almost every useful metric — making it a pretty heavy lift for engineers to use.

When Embrace set out to build a Flutter SDK, we wanted to create the best possible solution for devs. For us, this meant:

  1. Aiming for metrics parity with native SDKs
  2. Automating as much instrumentation as possible
  3. Keeping it “Fluttery”

Doing this wasn’t easy, so we turned to our partners at Very Good Ventures (VGV). A leading Flutter app development consultancy, VGV works with global brands to design, build, and scale successful apps.

They became our Flutter experts-in-residence, working closely with Embrace engineers and product managers to build our very first Flutter SDK — and very quickly.

Read on to see how we went from zero to beta in 3 weeks — and check out more detail about what we learned along the way from VGV.  

Following best practices

Having built an initial POC, our engineers enlisted VGV to ensure we were using the standards and best practices of Flutter development. After reaching code stability, we used VGV’s  very_good_cli to regenerate and migrate the plugin to a new and improved project structure.

VGV’s very_good_cli accelerates the project setup phase, a step that is generally time-consuming and tedious. We used the very_good_cli create command with the flutter_plugin template option to generate the code we needed for this SDK:

very_good create my_plugin -t flutter_plugin

We knew that following a federated plugin architecture would be ideal for the SDK, as it would allow for greater flexibility and ease of maintenance down the road (more on that below). Luckily, we were able to take advantage of VGV’s pre-built federated plugin template to facilitate this. Not only did using VGV’s template speed up our development process – cutting out the manual work of building the plugin from scratch – but it ensured that we were building to the standards and best practices unique to Flutter.

Ensuring 100% code test coverage

After the initial development phase, we needed to make sure that the codebase was well-tested. Here, we turned to VGV again to roll out this process with their very_good_coverage tool, which helps enforce code coverage metrics over time. As a result, our Flutter SDK has 100% test coverage — meaning that every single line of code is tested at least once. While this doesn't guarantee the codebase is bug-free, it’s a measure of quality that increases confidence in the functionality of the SDK.

From POC to beta

In the end, we rolled out a beta in about three weeks thanks to our joint expertise and collaborative mindset:

  • Embedded peer programming: Our Engineers worked closely with VGV Flutter experts throughout the project, deciding on architecture design and doing code reviews to ensure alignment.
  • VGV’s Flutter development tooling: With VGV’s very_good_cli, we were able to generate a federated plugin with a single command, saving us a huge amount of development time.
  • Embrace's observability expertise: We’ve built SDKs in other ecosystems, including the native iOS and Android solutions that serve as the foundation for any hybrid tooling.  Bringing that experience to the table ensured that our Flutter SDK would meet the market's needs.

Making it Fluttery

Building a tool is one thing, but ensuring that it provides a great experience for the end user is another. An important part of this project, therefore, was ensuring that the SDK felt familiar  – or “Fluttery” – to developers. We wanted to build an SDK that used structures, terminology, and standards that were familiar to devs used to working with Flutter – something tailored to them, rather than suggesting users accommodate their style in order to work with us. In our view, this is the only way to build a truly sustainable product, by meeting the needs of its community of users.

The way we structured APIs, taking into consideration how Flutter devs were used to working with plugins, was key here.

For example, do you set up a singleton with a bunch of static APIs (e.g. EmbracePlatform.instance.logError), or instead do you implement top-level functions such as logError? The singleton-and-static-APIs approach is common among other Flutter plugins (it's also used for Embrace's native SDKs), so this is what we went with to ensure ease and familiarity.

And what about pageviews or high-value areas? Tracking specific pages and key user flows is essential for uncovering where poor app performance impacts revenue (think “login”, “add to cart” or “checkout” flows). We knew we needed to get these right, down to all the finer details, for every platform our SDK supports.

While there are established mechanisms to track these across iOS and Android, Flutter is unique because of it's widget-based structure. The obvious choice, in this case, was using the NavigatorObserver API to track pageview events by overriding didPush, didPop, and didReplace. For more insight into this and code examples, head over to VGV’s page.

Adopting a federated plugin architecture

For the Flutter SDK, we implemented a federated plugin architecture.  Federated plugins decouple the logic of what the plugin does from the platform-specific implementations. This allows authors to define an interface and implement support for whatever platforms they want. Over time, the community can contribute support for new platforms without requiring changes to the plugin interface.

The benefits of this approach are the following:

  • Flexibility
  • Ease of adoption
  • Ease of maintenance
  • Community contribution

Since federated plugins provide an abstraction between the logic and the platform-specific implementations, they’re especially useful for larger companies with different platform teams. Separate Android and iOS teams at the same org can test, instrument, and set up automations for their own platforms independently of each other.

Right now, our Flutter SDK only supports Android and iOS as the underlying technology. But with the federated plugin architecture, support for other platforms can be added in the future, without overhauling any of the existing plugin code.

Getting started with Embrace for Flutter

Our SDK is now available in beta, with plans for a general release in January 2023. Like with the native Android and iOS versions, Flutter users can expect the following features out-of-the-box:

  • Crashes
  • Breadcrumbs
  • Errors in Dart code + in Android/iOS
  • Stack traces for errors
  • Logs
  • Network requests
  • Startup time and custom moments
  • Dart symbol file upload

For more information, check out our Flutter documentation.

Want to try it out for yourself? Head to our signup page and get started in minutes!

As with any beta, this SDK is still a work in progress and may have bugs.  If you find any issues or have any feature requests, please drop us a note at flutter@embrace.io.