Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closure Library is in Maintenance Mode #1214

Open
shicks opened this issue Nov 1, 2023 · 19 comments
Open

Closure Library is in Maintenance Mode #1214

shicks opened this issue Nov 1, 2023 · 19 comments

Comments

@shicks
Copy link
Member

shicks commented Nov 1, 2023

TL;DR: Closure Library will be sunset over the next 9 months, from November 1, 2023, to August 1, 2024. We no longer see it as meeting the needs of modern JavaScript development, and we recommend that users look for alternative solutions. Feel free to skip the background and go straight to the FAQ.


In the nearly 14 years since Closure Library was first made public, it's broken a lot of ground and paved the way for numerous ecosystem features that we take for granted today. At the initial release in 2009, Internet Explorer 8 was brand new, Chrome had just released version 3, the iPhone 3GS was fresh, and ECMAScript 5 was still just around the corner. Browser implementations varied widely in basic language and DOM support, with very different event models and quirks around every corner. Dependencies were generally managed manually by loading scripts in the right order.

Closure Library brought some amazing innovations to this ecosystem by providing a common library that glossed over browsers' many differences and allowed authors to focus on features and logic, rather than compatibility and quirks. It provided a full-featured debug loader, a wide swath of versatile tools, and a large gallery of prepackaged composable widgets that anybody could use to build web apps at a scale previously unimagined. And the type checker provided a level of static analysis that was previously unheard of in JavaScript.

But these same innovations that were groundbreaking at the time are now starting to feel a bit old and dated. CommonJS and ES Modules are the gold standard for dependency management; the language has evolved and added new, safer, and more ergonomic APIs for many basic features like classes or events; we now have TypeScript that provides a far more expressive type system than Closure; and groups like WICG and TAG have substantially reined in the divergences between different browsers. In short, the world has moved on and we believe it no longer needs Closure Library. These days, rather than elevating a project to modern practices, a dependency on Closure Library seems to feel more like something weighing a project down, holding it back from modern standards and greater adoption. In light of this, we've made the difficult decision that it's time to thank Closure Library and its many authors and contributors for all they've done for us over the years, and to bid it farewell.

FAQ

What is happening?

On November 1, 2023, we will transition Closure Library into maintenance mode. After this date, we will only push critical commits to the GitHub repository, respond to critical issues, and merge critical pull requests. On August 1, 2024, we plan to permanently freeze and archive the GitHub repository, after which no new commits or releases will be pushed at all.

During this time, we recommend looking for alternative solutions so that dependent projects can continue to receive critical security updates into the future.

Why are we doing this?

We no longer see Closure Library accomplishing its mission of improving the way JavaScript is written, and we honestly believe our users would be better served elsewhere. In particular, Closure Library's monolithic approach has become an anti-pattern in today's world of package managers and bundlers.

What about Closure Compiler?

We still believe that Closure Compiler is the best advanced optimizer in terms of minified size, as long as it can assume that all input code meets its strict requirements. While these requirements are sometimes difficult to guarantee for hand-written JavaScript, it's still very relevant as a compilation target for languages such as Java (via J2cl) or C++ (via emscripten), which can enforce the compiler's requirements more effectively. For users hand-writing JavaScript, we see TypeScript as a better authoring language, even if Closure Compiler continues to be used for optimization.

All this said, Closure Compiler and Library have a number of intersection points where they interdepend on one another. We are committed to retaining the core functionality in Closure Compiler, while dropping its dependency on Closure Library. This includes Closure dependency management (goog.module, goog.require, etc), reflection (goog.reflect.object, goog.reflect.objectProperty), defines (goog.define), and a few others.

What do I need to do?

No immediate action is required. A final version of the library will remain available for download from GitHub and NPM indefinitely (even after all updates are stopped), and API documentation will remain available at google.github.io/closure-library/api. There are no plans to remove any hosted versions of the library from CDNs. You can continue to use any previously-published versions of the library with no interruption as long as it serves your purposes. With that said, however, migrating to modern alternatives will likely be required at some point in the future to keep up with the ever-evolving web and security ecosystems.

What alternatives should I consider?

In the last decade, the NPM ecosystem has flourished. For most use cases where JavaScript's built-in solutions are insufficient, a quick search on NPM will turn up plenty of active projects that are likely to be better integrated with modern practices and more responsive to issues. While we can't endorse any of the non-Google libraries below, we list a few suggestions to help start a search:

  • For many parts of the library (goog.array, goog.dom, goog.events, goog.json, etc), JavaScript's built-in solutions should be sufficient.
  • For many special-purpose packages (math, data structures, other algorithms), a small focused library is often better than Closure's monolithic approach.
  • For networking (goog.net), much of the older functionality is subsumed by fetch and the streams APIs. WebChannel will live on in some form to support Firebase.
  • For SafeHTML (goog.html), we recommend migrating to safevalues.
  • For cryptography (goog.crypt), we recommend the built-in crypto.subtle API, or targetted utility libraries.
  • For internationalization and localization (goog.i18n), we recommend the built-in Intl API
  • For accessibility (goog.a11y), ARIA and semantic HTML are now much more universally usable.
  • For protocol buffers (goog.proto, goog.proto2), consider protobufjs or ts-proto.
  • For UI components (goog.ui and other CSS/style-related packages), consider any of the modern frameworks (Angular, React, Lit, Vue, etc).
  • For rich text editing (goog.editor), there are numerous modern libraries (Quill, Slate, TinyMCE, etc).
  • For testing, consider any of the modern BDD frameworks (Jasmine, Chai, Mocha, Jest, etc).
@shicks shicks pinned this issue Nov 1, 2023
copybara-service bot pushed a commit that referenced this issue Nov 1, 2023
RELNOTES: Closure Library is now in maintenance mode. See #1214
PiperOrigin-RevId: 578610862
Change-Id: I0cf1711a76ad2cf61ad50a88a9699a1859b218e9
@rome-user
Copy link

Hello,

Although I don't like the news, I am still happy that Closure Compiler and Closure Library has existed for so long! I have one minor question, specifically:

We are committed to retaining the core functionality in Closure Compiler, while dropping its dependency on Closure Library. This includes Closure dependency management (goog.module, goog.require, etc), reflection (goog.reflect.object, goog.reflect.objectProperty), defines (goog.define), and a few others.

In ClojureScript, the traditional module system of Closure is used heavily to achieve late binding, and goog.define is useful for compile-time constants like goog.DEBUG and goog.debug.LOGGING_ENABLED. I am wondering if there will be an equivalent of both of these features after the compiler drops dependency on Closure Library.

If not, what would be the "next best thing" in modern JS ecosystem to replace both of these things when using the Closure compiler?

@teppeis
Copy link
Contributor

teppeis commented Nov 2, 2023

How about Closure Templates?

@shicks
Copy link
Member Author

shicks commented Nov 2, 2023

@rome-user

In ClojureScript, the traditional module system of Closure is used heavily to achieve late binding, and goog.define is useful for compile-time constants like goog.DEBUG and goog.debug.LOGGING_ENABLED. I am wondering if there will be an equivalent of both of these features after the compiler drops dependency on Closure Library.

goog.DEBUG is defined in base.js. Some portion of base.js will be moved into the compiler in some form, to be determined over the next few months. goog.DEBUG, specifically, does not actually have any direct intersection with the compiler, so you could easily make your own version of that, possibly even named the same thing if you want backwards compatibility. LOGGING_ENABLED toggles features of the goog.log library - in the long run, you'd probably be best to find a different logging library, such as any of these browser-compatible libraries, or obviously an even larger set if you're not in the browser. Unfortunately, I'm well aware that the broader ecosystem doesn't have a concept that quite maps exactly to goog.define and works across enough optimizers that libraries would adopt it - but a small shim layer could potentially bridge the gap, whereby you make your own goog.define and your exported (top-level/static) functions are no-ops if it's not set.

If not, what would be the "next best thing" in modern JS ecosystem to replace both of these things when using the Closure compiler?

As long as you're using Closure Compiler, you can still make whatever defines you want. It's ultimately up to the library how it's going to be configured, and there's no standard (across all optimizers) way to do compile-time constants. I believe the closest thing to a standard (at least for goog.DEBUG) is the NODE_ENV environment variable. Making this work smoothly enough across enough optimizers that libraries can just depend on it existing is a dream of mine, but sadly I'm not hopeful about it ever actually happening.

@shicks
Copy link
Member Author

shicks commented Nov 2, 2023

@teppeis

How about Closure Templates?

My understanding of Closure Templates is that it's been hobbling along with minimal maintenance for a while. It's maintained independently from Closure Library, so this announcement doesn't affect it directly. Theh currently plan is that it will fold anything it needs to from Closure Library into its own project, so that it's more self-contained. That said, my personal take on it is that it's not really a thriving project anymore, and even if it's not (yet) deprecated, you're still probably better off finding a more modern alternative, such as Lit, Web Components, or one of the many [TJ]SX-based libraries/frameworks.

@banguit
Copy link

banguit commented Nov 6, 2023

What the alternative to goog.ui.Component to have best compatibility with Closure Compiler?

@shicks
Copy link
Member Author

shicks commented Nov 6, 2023

@banguit

What the alternative to goog.ui.Component to have best compatibility with Closure Compiler?

We've used Lit and Angular quite successfully with Closure Compiler. I'd assume Web Components (being a DOM standard at this point) should also work well.

@bcsgh
Copy link

bcsgh commented Jan 8, 2024

  • Are there any good replacement for the typing properties of goog.dom.createDom and goog.dom.TagName?
  • Does the compiler have documented and official support for deducing the correct Element sub types when using the top post's suggestion of "JavaScript's built-in solutions"?
  • Does JS have a built-in solution that can be used to get compile time errors when a tag name is typo'ed?
  • Are there any good "fail at compile time" replacements for goog.events.EventType?

Just in general; it would be nice to have a wiki or set of .md doc people can send PRs to with a mapping from existing libs to "things people have experience replacing them with". The further projects like this can stay away from the perception of doing a "we got board and lost interest, you're all on your own, not sorry, (╯°□°)╯︵ ┻━┻" the more likely people are to be willing to adopt other projects published by Google.

@lemito
Copy link

lemito commented Jan 14, 2024

Hello. Is the project closed inside Google as well? So search engine, Workspace(including gmail) and other products using Closure Library will move to other technologies?

@bcsgh
Copy link

bcsgh commented Jan 14, 2024

Hello. Is the project closed inside Google as well?

I have a strong suspicion that internally (most) stuff was transitioned before the announcement. At least as of a few years ago, Google had a habit of deprecation of old stuff before the new stuff is ready, but would keep it working as long as necessary. The odds that no must-fix bugs would be found in the time since the last update is slim to none if it was still being used.

@lemito
Copy link

lemito commented Jan 15, 2024

Hello. Is the project closed inside Google as well?

I have a strong suspicion that internally (most) stuff was transitioned before the announcement. At least as of a few years ago, Google had a habit of deprecation of old stuff before the new stuff is ready, but would keep it working as long as necessary. The odds that no must-fix bugs would be found in the time since the last update is slim to none if it was still being used.

To be honest, it's still not very clear what the fate of this library is.
My guess is that Google for Gmail, GSearch, etc. will continue with a separate, internal branch of the closure library or will seamlessly transition to their other solutions - angular 17/lit-html/server rendering via java closure-templates.
No comments from the developers yet and probably won't be, although it would be interesting to see the "inner kitchen" of modern Google, not through the research work of Larry Page and Sergey Brin.
Of course, this is most likely due to the policy of non-disclosure and confidentiality of information, but, again, there is a blog google search, but there rather exhibit DOODLES and information about the work of AI on the search, but not the principle of work at least the frontend of the search engine

@shicks
Copy link
Member Author

shicks commented Jan 18, 2024

@bcsgh

  • Are there any good replacement for the typing properties of goog.dom.createDom and goog.dom.TagName?

TypeScript handles this much better with string literal overloads of the built-in document.createElement function. For createDom, we've generally found that it lives in a kind of uncanny valley of utility, so we recommend against using it - you'r generally better off either just using createElement for very simple cases, or else a more proper templating system (e.g. TSX, Web Components, Lit, Angular, etc) for the more complex cases.

  • Does the compiler have documented and official support for deducing the correct Element sub types when using the top post's suggestion of "JavaScript's built-in solutions"?

Closure Compiler does not, but we're also moving away from the Closure type system in favor of TypeScript, which supports this very well (see above). As I said in the OP, the Closure ecosystem was a great solution in its early days, but we've come to realize that it's just not state of the art anymore and trying to use it is really going against the grain in the prevailing external ecosystem. As much as is feasible, we're embracing these external solutions that have now solved the problems better than we ever did.

  • Does JS have a built-in solution that can be used to get compile time errors when a tag name is typo'ed?

Again, see TypeScript and TSX.

  • Are there any good "fail at compile time" replacements for goog.events.EventType?

I believe TypeScript's standard declarations (lib.dom.d.ts, etc) declare a mapping from event name to expected event type, which should provide some safety there. If not, you could easily define your own TS enum, or there's likely an off-the-shelf library on NPM that provides one (or if not, you could contribute it for a much broader reach than anything you'd get with Closure, since TS just has a massively larger user base).

Just in general; it would be nice to have a wiki or set of .md doc people can send PRs to with a mapping from existing libs to "things people have experience replacing them with". The further projects like this can stay away from the perception of doing a "we got board and lost interest, you're all on your own, not sorry, (╯°□°)╯︵ ┻━┻" the more likely people are to be willing to adopt other projects published by Google.

This is a great idea, but I'm not sure having it in this repo is the right place, since it's due to be archived later this year, at which point it would become read-only. GitHub is a pretty democratic place, so if anybody feels strongly about it, you're more than welcome to make such a repository and link it here for the benefit of future readers.


Finally, we are still here, and we check this issue roughly weekly. I can't say much about Google's internals, but as much as possible, in areas like this where the Google-built solution has fallen behind the industry standards, we're trying to migrate to better external solutions, though this is sometimes very challenging. For external users in a similar boat, we feel your pain (first hand) and you can keep using Closure Library (in its current state) as long as you need to, but we simply can't in good conscience recommend anyone adopt it today given the many better alternatives.

@dpup
Copy link

dpup commented Jan 18, 2024

I've been out of google 12 years and can't quite believe Closure still exists. Thanks to everyone who has maintained and improved it over the years. It's come a long way from the days when a static bundle was being hosted on a workstation under my desk in building 47.

@lemito
Copy link

lemito commented Jan 21, 2024

Finally, we are still here, and we check this issue roughly weekly. I can't say much about Google's internals, but as much as possible, in areas like this where the Google-built solution has fallen behind the industry standards, we're trying to migrate to better external solutions, though this is sometimes very challenging. For external users in a similar boat, we feel your pain (first hand) and you can keep using Closure Library (in its current state) as long as you need to, but we simply can't in good conscience recommend anyone adopt it today given the many better alternatives.

Sorry, but since the closure library goes into maintenance mode and then archiving, how would a j2cl that transpiles java code into js code work? It also uses the closure library

@shicks
Copy link
Member Author

shicks commented Jan 22, 2024

@lemito

Sorry, but since the closure library goes into maintenance mode and then archiving, how would a j2cl that transpiles java code into js code work? It also uses the closure library

Yes, j2cl depends on both Closure Compiler and Closure Library. We are committed to ensuring it continues to work. The library functionality that j2cl relies on will be folded into either the compiler or into j2cl's repository, depending on what makes the most sense. We'll be figuring out the details in the next few months.

@seyoung-song-walmart-com

What is the best alternative for implementing grpc web client using Bazel? The closure example code looked like the most clean one that I could find in Google search.

@sampajano
Copy link
Contributor

sampajano commented Mar 21, 2024

@seyoung-song-walmart-com Hi! Do you mind start a discussion on the question you have instead? Could you also provide pointers to the "closure example code" you referred to so we can better understand your question? Thanks! Typically, npm would be the recommended way to use grpc-web (instead of Bazel).

@seyoung-song-walmart-com
Copy link

seyoung-song-walmart-com commented Mar 21, 2024

@sampajano Opened a discussion. grpc/grpc-web#1415. Using Bazel is necessary because all codes are maintained in a Bazel based monorepo. Here is example link. https://github.com/stackb/rules_proto/blob/master/example/routeguide/closure/client.js.

@lemito
Copy link

lemito commented Mar 21, 2024

@sampajano Opened a discussion. grpc/grpc-web#1415. Using Bazel is necessary because all codes are maintained in a Bazel based monorepo. Here is example link. https://github.com/stackb/rules_proto/blob/master/example/routeguide/closure/client.js.

This is not the only Google project using the Closure Library, there is also j2cl - they do their fork to keep the project running.
So I think they will just develop their version or maintain it internally and only put out versions that affect application security

@shicks
Copy link
Member Author

shicks commented Mar 21, 2024

This is not the only Google project using the Closure Library, there is also j2cl - they do their fork to keep the project running. So I think they will just develop their version or maintain it internally and only put out versions that affect application security

Thanks for bringing this up. To be clear, the Closure Library owners are working with these products to ensure that they remain intact. In cases where the internal remnants of Closure Library are still in use by these other projects, those projects are in the process of either migrating to more modern alternatives, or else adopting the shared code, in which latter case they'll release it (and any relevant security updates) per their own release schedules. Once the Closure Library repository is frozen/archived, it will no longer receive any updates (including security updates).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants