It's been five years since I first began using Google
Closure in a professional setting, and nearly as long
since I wrote my
introduction to it here. Over that time, we (Seattle-based
startup Appature, now IMS Health) used Google Closure to build a
very large web application for digital marketing.

Motivations

At the time we began using it, Google Closure had been public
for around 6 months. While it wasn't gaining much traction, it
promised to solve a number of difficult problems we were
experiencing. As with most web applications of the era, ours was
built using a small base library (prototype.js, though jQuery had conquered the world
for newer applications).

A key challenge when building a large application around a
small library is the need to constantly add supplemental libraries
to fill in missing functionality. Add a date picker, a drag &
drop library, and a rich text editor, and you've already added
hundreds of kilobytes to your application payload. Our worse case
pages had nearly 700 kilobytes of JavaScript spread
across several files (in an era where we still supported IE6, I
should add). Concatenation and minification were of little
help. Though we may have only been using a small percentage of
some of the libraries we were consuming, we had no reliable way to
eliminate the unused parts.

Worse, these additional libraries were typically authored by
a completely different team, individual or organization, making
code quality and even implementation patterns (such as event
handling) highly variable. Absent standards for UI elements, each
new library added additional costs for users as well. For example,
our pre-Google Closure application's WYSIWYG editor had its own
system for dialog boxes, whose look and function were completely
different from those found elsewhere in the application.

Adoption

At the time of our initial investigation, Closure was not
widely used outside of Google, and documentation (particularly
conceptual documentation) was scant. However, given its usage on
very high profile Google projects (Gmail, Docs, etc), we dove in
and have used Google Closure ever since.

The risk was worth taking, as Google Closure offered a
compelling solution to our most significant challenges. The
massive Closure Library -- hundreds of thousands of lines of good
quality JavaScript code -- matched well to our needs, and was
designed to be extended. For example, over the years we've added
extensive functionality to the WYSIWYG editor via plugins, which
look and feel like seamless extensions of the base editor.

More importantly, the Closure Compiler has allowed us to
turn the massive size of the Closure Library into a huge asset. We
compile our script with advanced optimizations, which eliminates
dead code automatically, meaning we only pay for exactly the code
we are using. Closure Complier also supports splitting code into
modules, which again is done automatically (like most non-Google
users, we use plovr). We
have a base module for common code and separate modules for major
areas of functionality (email, SMS, customer search, settings, and
many more).

Our consumption of Closure Library has grown significantly
over time. Shortly after our initial adoption, we extended our
localization support and found support for locale-aware parsing of
dates, numbers and currency right in the box. Below is a list of
classes and namespaces we've consumed from Closure Library. This
only accounts for elements of the library we've directly
referenced from our own application code:

goog.dom

goog.dom.forms

goog.array

goog.ui.Component

goog.asserts

goog.style

goog.string

goog.events.EventType

goog.events.Event

goog.events.EventHandler

goog.dom.TagName

goog.object

goog.async.Deferred

goog.events

goog.structs.Map

goog.dom.classes

goog.dom.DomHelper

goog.ui.Dialog.EventType

goog.ui.Dialog.ButtonSet

goog.json

goog.ui.Zippy

goog.net.XhrIo

goog.Timer

goog.ui.Dialog

goog.string.format

goog.ui.Popup

goog.ui.LabelInput

goog.dispose

goog.events.InputHandler

goog.userAgent

goog.dom.dataset

goog.debug.Logger

goog.ui.registry

goog.iter

goog.ui.Component.EventType

goog.testing.jsunit

goog.dom.query

goog.dom.NodeType

goog.ui.PopupBase.EventType

goog.ui.MenuItem

goog.events.EventTarget

goog.date.Date

goog.async.Throttle

goog.async.DeferredList

goog.ui.Menu

goog.ui.Control

goog.structs.Set

goog.net.IframeIo

goog.fx.DragDropGroup

goog.fx.DragDrop

goog.functions

goog.ui.editor.AbstractDialog.EventType

goog.ui.PopupMenu

goog.math

goog.fx.easing

goog.events.BrowserEvent

goog.editor.plugins.AbstractDialogPlugin

goog.Uri

goog.uri.utils

goog.ui.editor.ToolbarFactory

goog.ui.editor.AbstractDialog

goog.ui.ZippyEvent

goog.ui.Dialog.DefaultButtonKeys

goog.ui.DatePicker.Events

goog.positioning.Corner

goog.math.Coordinate

goog.fx.AbstractDragDrop.EventType

goog.dom.ViewportSizeMonitor

goog.date.DateRange

goog.Disposable

goog.ui.editor.ToolbarController

goog.ui.editor.DefaultToolbar

goog.ui.editor.AbstractDialog.Builder

goog.ui.decorate

goog.ui.ac.Remote

goog.ui.Tooltip

goog.ui.TabBar

goog.ui.Tab

goog.ui.SubMenu

goog.ui.MenuSeparator

goog.ui.IdGenerator

goog.ui.Dialog.Event

goog.positioning

goog.math.Size

goog.i18n.DateTimeParse

goog.fx.DragListGroup

goog.fx.Animation.EventType

goog.format.EmailAddress

goog.events.KeyCodes

goog.editor.plugins.LinkBubble

goog.editor.plugins.AbstractBubblePlugin

goog.editor.Field

goog.date.Interval

goog.History

goog.window

goog.ui.editor.TabPane

goog.ui.ac.AutoComplete.EventType

goog.ui.ac.AutoComplete

goog.ui.ToolbarSeparator

goog.ui.PopupColorPicker

goog.ui.MenuButton

goog.ui.ColorPicker.EventType

goog.ui.AnimatedZippy

goog.structs.Queue

goog.positioning.AnchoredPosition

goog.net.XhrManager

goog.math.Box

goog.locale

goog.iter.Iterator

goog.i18n.NumberFormatSymbols

goog.i18n.NumberFormat.Format

goog.i18n.NumberFormat

goog.graphics

goog.fx.dom.SlideFrom

goog.fx.dom.Slide

goog.fx.dom.FadeOut

goog.fx.dom

goog.fx.AnimationQueue

goog.fx

goog.events.KeyHandler

goog.events.InputHandler.EventType

goog.editor.range

goog.editor.plugins.UndoRedo

goog.editor.plugins.RemoveFormatting

goog.editor.plugins.ListTabHandler

goog.editor.plugins.LinkDialogPlugin

goog.editor.plugins.EnterHandler

goog.editor.plugins.BasicTextFormatter

goog.editor.Plugin

goog.editor.Link

goog.dom.Range

goog.debug.Logger.Level

goog.async.Delay

goog.ui.emoji.SpriteInfo

goog.ui.emoji.EmojiPicker

goog.ui.editor.messages

goog.ui.ac.Renderer

goog.ui.ac.InputHandler

goog.ui.ac.ArrayMatcher

goog.ui.ac

goog.ui.Zippy.Events

goog.ui.ToolbarMenuButtonRenderer

goog.ui.Toolbar

goog.ui.TabRenderer

goog.ui.TabBarRenderer

goog.ui.Prompt

goog.ui.PopupBase

goog.ui.ItemEvent

goog.ui.InputDatePicker

goog.ui.DatePickerEvent

goog.ui.DatePicker

goog.ui.Component.Error

goog.ui.ColorPicker

goog.ui.ColorPalette

goog.ui.ColorMenuButton

goog.ui.Checkbox

goog.testing.mockmatchers

goog.testing.asserts

goog.testing.StrictMock

goog.testing.MockClock

goog.testing.MockClassFactory

goog.structs

goog.string.linkify

goog.positioning.Overflow

goog.net.XhrLite

goog.net.IframeLoadMonitor

goog.net.EventType

goog.net.Cookies

goog.math.Rect

goog.i18n.currency

goog.i18n.NumberFormat.CurrencyStyle

goog.i18n.DateTimeSymbols

goog.i18n.DateTimeFormat

goog.graphics.Path

goog.fx.dom.Scroll

goog.fx.dom.PredefinedEffect

goog.fx.DragListDirection

goog.fx.DragDropItem

goog.events.KeyHandler.EventType

goog.events.KeyEvent

goog.editor.plugins.TableEditor

goog.editor.plugins.SpacesTabHandler

goog.editor.node

goog.editor.Table

goog.editor.Command

goog.editor.BrowserFeature

goog.dom.iframe

goog.dom.BrowserFeature

goog.debug.LogManager

goog.debug.ErrorHandler

goog.debug.Console

goog.date.UtcDateTime

goog.date.DateTime

goog.date

goog.color

As you would expect given its usage within Google, both
Closure Library and Closure Compiler have done an excellent job of
staying up-to-date. As HTML5 has blossomed, and browsers have
evolved, Google Closure has been quick to respond, adding to and
evolving its existing functionality.

Closure Today

If the measure of success for a JavaScript framework is
popularity, Google Closure has failed miserably. It's old, unsexy,
and has missed its turn on the hype train. Google spends no effort
on PR for the library, and seems content with it quietly powering
the majority of its flagship applications. And given that, the
lack of hype has mattered very little to us, as it's been a very
good solution to our problems over the past five years.

That's not to say that adoption doesn't matter. The absence
of a rich community around Google Closure has been
disappointing. Only a single
book on Google Closure has been published, and the
surrounding tools have been slow to evolve. Contrast this with
Angular, which has
achieved off-the-charts hype and has developed a massive community
despite minimal usage in production Google applications. Many
books and countless blog posts have been authored explaining
various patterns and concepts, making it much easier to get
started.

Despite the lack of popularity, a number of companies have
successfully used Google Closure for their production
applications. Medium,
Yelp, CloudKick
(acquired by Rackspace), Cue
(acquired by Apple), and IMS Health (my
company) all use (or have used) Google Closure to power their
production applications. And, importantly, the majority of
Google's flagship applications continue to be powered by Google
Closure.

Looking Ahead

So, what about the next five years? I expect that we'll be
using Google Closure in some form over that time period, though
our usage will likely evolve. One area where we're currently
venturing outside of Closure Library is for our UI components,
which have not been as quick to evolve as other parts of the
library. Specifically, we're using React, whose
component architecture has fit in very nicely with our existing
Google Closure code. With a bit
of effort, React components can also take advantage of
Closure Compiler.

ClojureScript

One of the more innovative projects in the JavaScript
landscape is ClojureScript,
a version of Clojure
which compiles to JavaScript. Far more than just an alternate
syntax for JavaScript, ClojureScript also makes consuming Google
Closure incredibly easy (that it rhymes is purely a confusing
coincidence).

ClojureScript bundles Closure Library and seamlessly
integrates Closure Compiler, requiring no extra tools to gain all
of Google Closure's benefits. It is also capable of solving one of
Google Closure's biggest annoyances -- its verbosity when used
directly from JavaScript. Consider the following example from my
original
introduction, compared to its ClojureScript
equivalent:

The ClojureScript community over the past couple of years
has been a great source of innovation for application models
using React's immediate mode rendering (read this
post for a taste). Libraries like Om and Reagent
have demonstrated the simplifying effect immutable data brings to
UI development, and re-frame has
provided a pattern for extending beyond the rendering
layer.

Figwheel
deserves special mention, as it enables a unique interactive
coding environment. Using Figwheel to build reloadable UIs in the
style promoted by the libraries above, you can update code live
while in the middle of a user workflow. The concept is best
presented visually, see this brief
video by the author, Bruce Hauman. Having built
a couple of UI applications in this style, the traditional browser
refresh workflow simply feels slow.

Googe Closure is a first class citizen in the ClojureScript
universe. Consider the recent support for Closure
Compiler modules, and the manylibraries
which provide idiomatic wrappers around the robust functionality
of Closure Library. ClojureScript promises to be a well supported
platform for building rich web applications with Google Closure
for many years to come.

Fortunately, we have plenty of tools for making things
easier and faster to write. One of my favorites is YASnippet, an
Emacs extension which offers TextMate-inspired support for
snippets. This forms the basis for Closure Snippets. The snippets
in the package are designed to run when js2-mode is
active.

I put together a quick screencast to show Closure Snippets
in action. As in my previous Emacs
screencast, I've used a slightly modified but mostly
standard Emacs configuration:

Late last year, Google releasedClosure
Tools, a trio of open source technologies aimed at
developers writing large scale JavaScript applications. Included
in the initial release were Closure Compiler, a sophisticated
JavaScript compiler, Closure Library, a massive library of
JavaScript code designed for use with the Compiler, and Closure
Templates, a templating system implemented in both JavaScript and
Java.

The sales pitch was certainly compelling. Closure had been
used internally at Google since 2005, with contributions from over
400 engineers. This was the technology that powered Gmail, and
several other high profile Google applications (Docs, Reader,
Calendar, Maps and Wave amongst them). Google pitched it as their
"standard library" for JavaScript-based applications. It
would have be reasonable to expect that the hype meter would have
been off the charts.

Despite this, the response was rather tepid. The
announcement spread broadly, but the standard response seemed to
be "so what?". Not much has changed in the six-plus months
since its release, either. In the past 30 days, there have been a
grand total of three questions tagged with google-closure
on Stack
Overflow. During the same time period, there have been
3,161 questions about jQuery.

So, what's the problem? Is it the confusing name (a closure
is a JavaScript language feature)? "Anti-hype" due to the
fact that it was released by Google? Exhaustion from the rapid
pace of new JavaScript library releases? A lack of conceptual
documentation? Or, is it just too complex to actually use?

I think all of these may be factors to some degree, but the
real reason is much simpler: it's simply not the right tool for a
lot of applications. That's not intended as a criticism of Closure
Tools, it's just that it was designed with far different goals
than other popular libraries like, say, jQuery and Prototype.

For small applications, blogs, design galleries, or static
content sites which just need some simple form validation, Closure
is probably overkill. It is a perfectly suitable
solution, as the Closure Compiler enables an efficient footprint
for applications of any size. However, the learning curve is quite
steep, there are far fewer examples, and you need to find a way to
integrate the compiler into your workflow. With a library like
jQuery, you just add a script reference (if using a CDN,
you don't even need to upload it to your server) and start coding
away.

So aside from large Web applications from Google, who is
Closure for? Having studied Closure exhaustively for the past few
weeks, I would suggest that it is an excellent option to consider
for any "medium-plus" sized application, regardless of the
back-end "technology stack". These applications will almost
always involve multiple developers, and are likely to contain at
least 100 kilobytes of non-library source code. If there is no
build system in place to combine scripts, an average page in an
application of this size probably references 5 to 10 external
scripts, if not more.

If your application has reached this level of complexity (or
you project it to), this is a good starting point where the
benefits of Closure start to become significant. The impact of
Closure Compiler on your code's execution speed and size (and, if
your scripts aren't being combined, HTTP request overhead) will be
significant, and you're likely to be in position to benefit from a
large portion of Closure Library as well. As your application
grows, so do the benefits. Let's take a closer look at the two
primary components of Closure Tools (we'll not be covering Closure
Templates).

Closure Compiler

The Closure Compiler is the arguably the flagship component
of Closure Tools. The Compiler supports two primary optimization
modes: "minification" (whitespace-only or simple) and
"advanced compilation".

A JavaScript minifier is nothing new. There have been high
quality minifiers available for several years. A JavaScript
compiler isn't even necessarily new, as compilers from other
languages to JavaScript have also been floating around for some
time. What is unique about Closure Compiler is that it is a
JavaScript-to-JavaScript compiler, capable of performing
optimizations to JavaScript code that were previously unheard
of.

Closure Compiler can be used as a standalone component
against an existing JavaScript codebase, or in concert with
Closure Library, which has been explicitly designed for maximum
optimization when used with the compiler. It's easier to
understand the power of these advanced compilation features by way
of a simple example. Consider the following script:

After running this through the compiler in advanced mode
(which you can easily try for
yourself), we're left with the following:

alert("Hello, friend!");

The result speaks for itself. The compiler eliminated dead
code, inlined functions, optimized string concatenation, and left
us with a significantly smaller but functionally identical
result.

Hey, where'd my functions go?

It might seem strange or abitrary that in the examples
above, the unused functions simply disappeared in the output. The
compiler considers this removal perfectly safe and reasonable
because it assumes that you have provided it with the entire
source code for your application. If you want one of your
functions to be available outside of the context of your core
JavaScript code (say, from a script element in
an HTML page), you need to explicitly tell the compiler to export
it. See the compiler
documentation for details.

This isn't to say that there won't be any function calls in
your final compiled output if you don't export anything. Closure
Compiler will only inline code when it considers it
appropriate. When not inlining, functions will typically be
renamed. If the compiler chose not to inline our
hello function, for example, the output
would look something like the following:

function a(b){alert("Hello, "+b+"!")}a("friend");

I'm supposed to debug that?

If your reaction to the above code is one of terror, you are
probably not alone. Anyone who has written large systems in
JavaScript knows that debugging code is an inevitable part of the
process. The significant optimizations provided by Closure
Compiler might make your code smaller, but they also make it
extremely difficult to map back to the original code. If you
experience a runtime failure that only happens in the compiled
code, what do you do?

Fortunately, Closure Compiler is capable of creating a
source map, which enables areas of the compiled code to be
definitively traced back to the original source from which it was
compiled. Even better, you don't have to work with the source map
file itself, as Google provides Closure
Inspector, a Firebug extension (yes, Firefox only for now)
which integrates into your standard debugging experience.

Is that it?

While Closure Compiler is an excellent tool for optimizing
code size and execution speed, that's not the only value it
provides. It also supports a huge number of JSDoc
annotations which enable it to help you find bugs in your
code (these also allow the compiler to even better optimize your
code). For example, we could redefine our
hello function from above with a type
annotation as follows:

Here, we have told the compiler that we expect a single
parameter of type string. Now, let's add some
problematic calls to the function:

hello();
hello(3.14);

Now, when we compile this code, the compiler issues the
following warnings.

JSC_WRONG_ARGUMENT_COUNT: Function hello: called with 0 argument(s).
Function requires at least 1 argument(s) and no more than 1 argument(s).
at line 5 character 5
hello();
^
JSC_TYPE_MISMATCH: actual parameter 1 of hello does not match formal parameter
found : number
required: string at line 6 character 6

With large programs in particular, these warnings can help
you quickly isolate hard to find bugs that would otherwise only be
visible at runtime. The only downsides are the need to add the
JSDoc tags to your code comments (though these are also quite
useful as documentation when reading the code), and the need to
"cast" from time to time, as below:

Closure Library

Closure Library is a massive library of JavaScript code
optimized for use with Closure Compiler. In theory, pairing it
with the Compiler is optional. And in fact, this is an incredibly
important feature in development environments, as it makes the
compilation step optional and dramatically speeds some stages of
development. In production, however, use of the compiler is
not optional, as the uncompiled library code is very
large, and the strategy used to include the files is not designed
to be efficient.

So just how big is Closure Library? The following chart
provides some indication. This is the uncompressed, non-minified
JavaScript on-disk file size of a few popular libraries (excluding
test code), as reported by du. The file
sizes include comments and indentation, so it is not meant to be
indicative of the actual number of "lines of code". All
libraries shown are the current stable versions at the time of
this writing:

So yes, the library is indeed massive. But is it any good?
For starters, there are no "versions" of Closure Library.
The code is simply updated periodically in a public Subversion
repository, which is fed from Google's internal source control
system. That doesn't mean that it's "prerelease" (or
"beta") quality, it simply means that Google is confident
enough in the quality of the code that the latest release is
always considered to be (in their own words) "very
stable". Many parts of Closure Library are actively in
production at Google, and it comes with a massive suite of unit
tests. At the end of the day, it's up to you and or your
organization to determine if it is "stable" enough for your
needs. Having spent a large amount of time in various modules of
the Closure Library code recently, my personal opinion is that it
is uniformly well designed, well documented, and very well
written.

So what's in there, taking up all of that space? A
surprising amount is in comments, believe it or not. Closure
Library is exhaustively documented, and most of the
documentation is inline. This makes browsing the code a great
strategy for learning more about Closure. As far as the code
itself is concerned, some portion of the library is dedicated to
things that would be broadly useful in any JavaScript project,
including those that do not target Web browsers (array,
crypt,
date,
math,
string,
and more). A bigger portion of the code is exclusively designed
for JavaScript applications targeting browsers (dom,
editor,
fx,
history,
style,
ui,
useragent,
and more). A good starting point for understanding what's
available in Closure Library is the demos
folder (index),
where you'll find examples for things as basic as event
handling, and as exotic as a popup
"emoji" picker. Lastly, Closure Library also includes
selected third party code. For example, Dojo's Query
implementation is exposed as
goog.dom.query.

Closure Library code is modular, with related code organized
into "namespaces". This organization is well suited for large
scale projects with large teams. Another advantage of this
namespacing strategy is that Closure Library is extremely unlikely
to interfere with existing libraries, as all of the library code
is organized under a single global symbol
(goog). Note that this does not necessarily
mean that other libraries will not impact the behavior of Closure
Library. Existing libraries that pollute the global namespace
unpredictably, or modify the prototypes of built-in JavaScript
types could cause Closure Library code to behave undesirably (as
it would with any other third party library). To put it more
succinctly, Closure Library plays well with others, provided that
they too play well with others.

The downside to the namespacing strategy is that your code
ends up being more verbose. There are many ways to control for
this. You might decide that your application won't need to
interoperate with other libraries, and can safely add aliases for
commonly used functions in the global namespace. For example, if
goog.dom.getElement is too much typing for your
taste, you can selectively trade off namespacing by simply adding
a global alias as $:

goog.exportSymbol('$', goog.dom.getElement);

There are, of course, risks to modifying the global
namespace in this fashion, so it's undoubtedly a good thing that
the Closure Library designers left the decision to us.

Closure Library vs. jQuery, Prototype

So if we don't modify the global namespace, what does
Closure Library code actually look like? This is probably easier
to understand by example. Following are ten simple code examples
comparing the syntax of Closure Library to two other popular
libraries: jQuery and Prototype. I created these examples by
looking through a few codebases built on top of the libraries,
choosing the most popular examples which corresponded to
functionality common to all three. My intent is not to make one
library look better than the other, but rather to compare the
style and syntax. The examples are functionally equivalent.

In general, the Closure Library examples are more verbose
than the equivalents written using jQuery and Prototype. After
being run through the compiler, they will be more compact at
runtime, but there is some extra visual overhead to deal with when
reading and writing Closure Library code. Of course, as discussed
above, Closure Compiler helps a great deal when writing this code,
as it can find bugs before you run them in the browser.

All of these libraries are quite easy to work with for such
trivial examples as those above. The real benefits of Closure are
found in larger codebases. If you're working on such a codebase,
or are about to, I strongly suggest giving Closure Tools a
look.