A Language to Fix the Web
Cast your mind back to 2011. The web was exploding with complex applications like Gmail and Google Maps, and JavaScript, the de facto language of the browser, was straining under the load. Google engineers, frustrated with maintaining massive JavaScript codebases,
envisioned a better way. Their solution was a new language, unveiled at a Danish conference: Dart. The original goal was breathtakingly ambitious. Dart wasn't just meant to be a language that compiled to JavaScript; it was intended to replace it, running natively in a dedicated Dart Virtual Machine (VM) inside the Chrome browser. To achieve this coup, however, Dart had to convince a world of JavaScript developers to switch. This led to the single most consequential decision of its early life.
The Compromise: Optional Typing
To make the transition from the loose, free-wheeling world of JavaScript as painless as possible, Dart's creators—including language design veterans like Lars Bak and Gilad Bracha—made a crucial compromise: types would be optional. A developer could add static types to their code for clarity if they wanted, but the language wouldn't enforce them. It was a 'gradually typed' system. The appeal was obvious. It created a shallow learning curve and allowed for flexible, script-like coding. This was a direct appeal to the established JavaScript community, a pragmatic choice designed for adoption. It was a feature, not a bug, born from a desire to be familiar and easy to learn.
The Hidden Cost of Flexibility
The plan to get a Dart VM into all major browsers ultimately failed. By 2015, Google shifted focus to making Dart an excellent language that compiles to JavaScript. And without the pressure of browser domination, the cracks in the optional-typing foundation began to show. The system, designed for flexibility, introduced a hidden cost. Codebases became fragmented, with a mix of typed and untyped code that was difficult for tools to analyze. More importantly, it meant that type errors—the very thing static types are meant to prevent—could still appear at runtime, crashing an application. It turned out that "optional" safety was often no safety at all. For a language that prided itself on performance and scalability, this unpredictability was a major liability.
The Painful Pivot to Soundness
By 2018, with the rise of the Flutter project, the Dart team knew a radical change was needed. Flutter promised high-performance, beautiful UIs on any screen, and it needed a language with rock-solid predictability. Optional typing wasn't going to cut it. This began the monumental effort to pivot Dart to a "sound" type system. With the release of Dart 2.0, this transition began, but the biggest leap was the introduction of sound null safety, which rolled out years later. This feature guarantees that if the compiler determines a variable isn't null, it can never be null, eliminating a whole class of common bugs. Migrating an entire language and its ecosystem to this new model was a massive, multi-year undertaking, requiring developers to update their code and adopt a stricter way of thinking.
The Decision's True Legacy
This is the true legacy of that "forgotten" decision. The initial choice of optional typing was a pragmatic compromise that helped Dart survive its early years. However, the subsequent, difficult decision to abandon it in favor of a sound, null-safe type system is what allowed Dart to thrive. That arduous journey forged it into the language it is today: robust, incredibly well-tooled, and performant. The soundness of its type system is a key reason why Flutter can deliver the speed and reliability it's known for. The pain of the migration created a language that was not just designed, but battle-tested and hardened by its own history. The original sin was forgiven, and in fixing it, Dart found its true calling.











