Hello web devs! CanJS 3.0 is out. It has a new developer-centric website and new features like:
- Real-time support
- Observables that are faster, use getter/setters instead of .attr(), throw errors if you set an undefined property, and can use event streams.
- Converters that make two-way bindings easier.
If you are ...
- new to CanJS - check out the Guides page to get started using the framework.
- using previous versions - read the Migration Guide on how to upgrade to 3.0.
- interested in learning more about CanJS's technical accomplishments - head over to the Technical Highlights page.
A New Mission and Goals
While we're very excited about 3.0's new features, this release ultimately represents an understanding and embrace of CanJS's identity — adapt or die.
- Custom DOM libraries, then PrototypeJS, then jQuery
- Event delegation
- Live-binding templates
- Custom elements
- Diffing templates
- Event streams
Despite this constant change, we've worked to provide a framework that makes it simple and fast to develop complex applications. But, we've come to realize that "simple and fast" hasn't been our ultimate goal. It has been adapting to new ideas. So for CanJS 3.0, we rewrote our mission statement to express how CanJS's real identity benefits its users:
We don't know what the future of technology is going to be. No one does. With this in mind, we've pursued the following goals:
1. Make future upgrades easier and more frequent.
2. Ensure that the code you produce today is not going to be a liability tomorrow, but will retain its value for as long as possible. (Code Longevity)
3. Embrace experimentation and outside tools.
The First Step - Independent Repositories
The first step towards accomplishing these goals was to enable the asymmetrical development of CanJS. This meant moving almost every module in CanJS to its own independent repository, each with its own npm package and semantic version number. CanJS is now comprised of about 40 different repositories. You can find more details about this on CanJS's Technical Highlights page.
If a CanJS 2.3 to CanJS 3.0 upgrade looks like this:
Future upgrades should look like this:
Upgrading will be much smoother and more frequent. Releases containing bug fixes and features will be separate from releases containing breaking changes. We've already had about 40 sub-project releases since 3.0.
This also means that legacy libraries, like can-ejs, can continue living through community-driven fixes and releases. Legacy code doesn't die simply because it's not included in the core build. It lives on. Viva la EJS!
Finally, individual repositories lay the groundwork for experimentation. It's easy (using the DoneJS plugin generator) to create a CanJS library or extension in another repository and publish it to npm. New releases can be published easily and often, without releasing the rest of CanJS. And, we can now give these things visibility in the ecosystem collection.
An example of embracing experimentation and outside tools are the can-stream and can-define-stream packages. They integrate functional reactive programming using Kefir.js into CanJS. In their own repositories, these packages can be quickly developed independently from the rest of CanJS.
CanJS 3.0 has a number of other changes that are a starting point for CanJS's goals. For example:
- can-define can be a mixin to a `class` constructor
- can-fixture works directly against the XMLHTTPRequest object, making it useful in any framework
- can-connect is mixin based, also enabling it to be useful to other frameworks
As we move forward, we will continue making CanJS feel less like a framework and more like a collection of high-quality and useful libraries. How we do this will be written in an upcoming roadmap article.
CanJS isn't a framework anymore. It's about embracing a changing technology landscape. It's about making useful tools for the community. It's about living up to the motto: We Can JS.