Skip to main content

From GWT to AngularDart: a case study with source code

Lots of interesting articles about Dart have been cropping up on lately. We've decided to cross post them here so that followers of this blog won't miss out on them. We'll start by Istvan Soos's GWT-to-Dart case study, published on Friday. — Filip Hracek

Earlier this year I was asked if there’s a good way to compare developing web UIs in Google Web Toolkit (GWT) vs. Dart, specifically AngularDart. Having worked with both GWT and Dart, I had a good idea of the differences, but as I thought more, I started to wonder how hard it would be to migrate a GWT application to AngularDart. This article describes what I’ve found while doing just that.

The GWT Mail Sample was an ideal place to start: it’s much more than a trivial example, with diverse features and complex UI interactions, yet it’s still manageable in size.

If you’re in a hurry, take a look at the working demo and the source code, or scroll to the bottom for the conclusions.

Screenshot of the demo.

The method of migration

I’ve done the migration without any automated compiler. While it may be possible to write a tool to automatically convert the GWT templates to Angular, or the backing Java code to Dart, I wouldn’t suggest doing it that way. Chances are that the template, the styling, or the Java code uses patterns that are better served with new approaches. I’ll list a couple of these new approaches in the next section.

My process was very simple. I put the GWT and the AngularDart code in the same git repository and did the following cycle:

  1. Select a small or medium-sized chunk of the GWT codebase. Usually this was a single widget, or a smaller part of a complex widget.
  2. Carefully explore the features and edge cases that are in the code. Most of a proprietary codebase will be some kind of edge case that somebody stuffed in it. If there are more than 5 edge cases, it is a good indication that the task is too large and needs to be split into multiple chunks.
  3. Implement the selected part in AngularDart. This sounds simple, because it is simple. :-)
  4. Delete the selected part from the GWT codebase. The GWT application will no longer build, but you can easily track the parts that you haven’t migrated yet.

You can check my progress and individual steps either by observing the commit history, or by looking at the file that I was writing along as I was doing the changes. One interesting observation: writing down the changes took much more time than implementing the code in AngularDart.

Old solutions vs. new ones

The bulk of the migration is straightforward: simple templates and styles can be mapped to their Angular counterparts easily. I won’t waste your time with minute details; instead I’ll just talk about the parts that differ.

The first and most obvious difference is the design: the Angular version uses material widgets from the angular2_components package. The package has a lot of useful components, if you are starting with AngularDart, you should try to go with that. While both stacks have a great selection of ready-to-use components, and most of them have 1:1 mappings with regard to features and settings, sometimes you need to use your judgement on which to use or select.

Watch the new version alongside the old one. AngularDart Components make it easy to have nice animations and consistent component views.

I missed a few things that aren’t available yet in AngularDart Components, like a table and tree component. However, as you can see in the log, it was really easy to implement them with Angular’s *ngFor templates. For example, the list of mail items is handled by the following template, which is much simpler than GWT’s table initialization in

<div *ngFor="let item of items"
  <div class="col sender">{{item.sender}}</div>
  <div class="col email">{{}}</div>
  <div class="col subject">{{item.subject}}</div>

I was told that team is working on open sourcing more components; fingers crossed that a more complex table will be included soon.

Less intriguing, but an important difference is the lack of static variables and the handling of singleton instances. In the GWT version, the list of email messages is stored in a static field in In the Dart version, the same (and much more) functionality is handled by MailService, which is injected and better for unit testing.

I’ve started with a mock implementation for easier development (also to match the GWT version), while later on it is easy to plug in a real API behind the web client. For example, configuring the injection is as simple as the following code. Switching to a real implementation would be just changing the useValue: part of it.

Change to real implementation when ready.

On a more subjective note, I find the separation of code, HTML template, and CSS styles much better in AngularDart than in GWT. The GWT codebase allowed sprinkling the Java code with both styling details and template construction, and those parts were the hardest to migrate to a cleaner version.

End result by the numbers

While the AngularDart version has more features, and I’ve implemented custom components like the tree, overall I needed to write less code than what was needed for the GWT original. Depending on how you count, code size is down by 30%.

I was developing the application using Dartium, so I didn’t need to compile the Dart code to JavaScript; everything was done with a low-latency type-save-refresh cycle. However, the end result needed to be compiled to JS, and it may provide value to compare the numbers. On my Macbook Pro, the GWT applications’ compile times were:

  • 26 seconds for 1 permutations,
  • 11 seconds if the Java source code was already compiled, and
  • 40 seconds for all 5 permutations.

The Dart version took about 15–20 seconds to compile to cross-browser ES5. That is not blazing-fast, but it is faster than the GWT compiler.

Compile times (in seconds)

Last, a few notes about the output JavaScript’s size. The GWT compiler produces different JS version for each permutation (target browser), while the Dart compiler emits only a single compiled version. GWT’s output was roughly 207 KB / permutation (1M total for all 5, 84 KB/permutation when compressed), while the AngularDart version resulted in 689 KB (178 KB compressed).

Considering that the application logic is more complex (for example: diverse widgets, ripples, more detailed mail item handling), the larger JS size is not a surprise, although I hoped it would be smaller. Fortunately for us, a huge part of it is “fixed cost”, and additional components increase the size only a little (proportional to their complexity).


Both technologies originate from Google and both are capable of supporting larger team sizes, but they represent two very different eras. I have found the GWT code harder to read and reason about; the AngularDart version is more compact and easier for me. But don’t trust my point of view blindly. I strongly suggest that you try out the application and check the source codefor yourself.

I have also found the material components refreshing, and most of the time they were out of my way. Compared to that, styling and customizing GWT components is harder, requiring time that would be better spent on the application itself.

If you are looking to migrate your GWT app to a newer technology, AngularDart is a viable option. After all, Google is doing the same thing: they are migrating their critical apps from GWT to Dart (see their AdSenseand AdWords interviews).

— István Soós, March 10, 2017, canonical link

Popular posts from this blog

Const, Static, Final, Oh my!

Posted by Seth Ladd

(This is an "oldie but a goodie" post originally written by Bob Nystrom. It is being posted here as the explanations still ring true.)

Bob writes:

"static", "final", and "const" mean entirely distinct things in Dart:

"static" means a member is available on the class itself instead of on instances of the class. That's all it means, and it isn't used for anything else. static modifies *members*.

"final" means single-assignment: a final variable or field *must* have an initializer. Once assigned a value, a final variable's value cannot be changed. final modifies *variables*.

"const" has a meaning that's a bit more complex and subtle in Dart. const modifies *values*. You can use it when creating collections, like const [1, 2, 3], and when constructing objects (instead of new) like const Point(2, 3). Here, const means that the object's entire deep state can be determ…

AngularDart 4

AngularDart v4 is now available. We've been busy since the release angular2 v3.1.0 in May. Not only did we "drop the 2", but we also improved the compiler and tightened up the framework to give you smaller code, we updated the package structure to improve usability, and we added several new features. Check out the updated documentation to get started.
Just angular Upgrading to v4 will require more than updating your version constraint. The package has changed names (back) to angular – dropping the 2. You'll need to update your pubspec.yaml and the corresponding imports in your code. In most instances, find-and-replace should do the trick. Going forward, the package will be called package:angular. We'll just update the version number.
Smaller code The updated compiler in 4.0 allows type-based optimizations that not only improve runtime performance but generate better code because we are able to strongly type templates. A big result of the update is that many ap…

The new AdWords UI uses Dart — we asked why

Google just announced a re-designed AdWords experience. In case you’re not familiar with AdWords: businesses use it to advertise on and partner websites. Advertising makes up majority of Google’s revenue, so when Google decides to completely redo the customer-facing front end to it, it’s a big deal. The Dart team is proud to say that this new front end is built with Dart and Angular 2. Whenever you asked us whether Google is ‘even using Dart for anything,’ this is what we had in mind but couldn’t say aloud. Until now. We asked Joshy Joseph, the primary technical lead on the project, some questions. Joshy is focusing on things like infrastructure, application latency and development velocity, so he’s the right person to ask about Dart.Q: What exactly did we launch on Monday?It’s a complete redesign of the AdWords customer experience that is rolling out slowly as a test to a small initial set of advertisers. The most noticeable thing is probably the Material Design look and f…