can
Version:
MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.
820 lines (560 loc) • 28.6 kB
HTML
<!--####################################################################
THIS IS A GENERATED FILE -- ANY CHANGES MADE WILL BE OVERWRITTEN
INSTEAD CHANGE:
source: [object Object]
@page guides/mission
######################################################################## -->
<html lang="en">
<head>
<meta charset="utf-8">
<title>CanJS - Mission</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="stylesheet" type="text/css" href="../static/bundles/bit-docs-site/static.css">
<link rel="shortcut icon" sizes="16x16 24x24 32x32 48x48 64x64" href="/docs/images/canjs_favicon.ico">
<link rel="apple-touch-icon" sizes="57x57" href="../../docs/images/canjs_favicon_57x57.png">
<link rel="apple-touch-icon-precomposed" sizes="57x57" href="../../docs/images/canjs_favicon_57x57.png">
<link rel="apple-touch-icon" sizes="72x72" href="../../docs/images/canjs_favicon_72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="../../docs/images/canjs_favicon_114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="../../docs/images/canjs_favicon_128x128.png">
<link rel="apple-touch-icon" sizes="144x144" href="../../docs/images/canjs_favicon_144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="../../docs/images/canjs_favicon_152x152.png">
<meta content="yes" name="apple-mobile-web-app-capable">
<meta name="apple-mobile-web-app-status-bar-style" content="white-translucent">
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-2302003-11', 'auto');
ga('send', 'pageview');
</script>
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger"/>
<label for="nav-trigger">Menu</label>
<div id="everything">
<div id="left" class="column">
<div class="top-left">
<div class="brand">
<div class="logo">
<a href="../../index.html" alt="CanJS"></a>
<div class="dropdown project-dropdown">
<a href="https://donejs.com/">DoneJS</a>
<a href="http://stealjs.com/">StealJS</a>
<a href="http://jquerypp.com/">jQuery ++</a>
<a href="https://funcunit.com/">FuncUnit</a>
<a href="http://documentjs.com/">DocumentJS</a>
</div>
</div>
<div class="version">
<div class="version-number">
3.0.0
</div>
<div class="dropdown version-dropdown">
<a href="https://v2.canjs.com">2.3.27</a>
</div>
</div>
</div>
<div class="search-bar">
<p>
</p>
</div>
</div>
<div class="bottom-left">
<div class="social-side-container">
<ul class="social-side">
<li>
<a class="header-mobile github" href="https://github.com/canjs/canjs" target="_blank"><img class="social-icon-small" src="../../docs/images/github.png">Github</a>
</li>
<li>
<a class="header-mobile twitter" href="https://twitter.com/canjs" target="_blank"><img class="social-icon-small" src="../../docs/images/twitter.png">Twitter</a>
</li>
</ul>
<ul class="social-side">
<li>
<a class="header-mobile" href="https://gitter.im/canjs/canjs" target="_blank">Chat</a>
</li>
<li>
<a class="header-mobile" href="http://forums.donejs.com/c/canjs" target="_blank">Forum</a>
</li>
</ul>
</div>
<ul>
<li class="
parent
expanded">
<a class="page"
href="../guides.html"
title="Welcome to CanJS! These guides are here to help you develop and improve your relationship with CanJS. After all, picking a JavaScript framework is a commitment. We want CanJS to be the
framework you marry. This page helps you know how advance through the different stages of this
relationship:">
Guides
</a>
<ul>
<li>
<span>introduction</span>
<ul>
<li class="current
parent
expanded">
<a class="page"
href="mission.html"
title="Learn about CanJS's mission, why it matters, and how we've worked (and will keep working) to accomplish it.">
Mission
</a>
</li>
<li class="
">
<a class="page"
href="technical.html"
title="">
Technical Highlights
</a>
</li>
<li class="
">
<a class="page"
href="who-uses-canjs.html"
title="">
Who uses CanJS?
</a>
</li>
</ul>
</li>
<li>
<span>experiment</span>
<ul>
<li class="
">
<a class="page"
href="chat.html"
title="This guide walks through building real time chat application with CanJS's Core libraries. It takes about 30 minutes to complete.">
Chat Guide
</a>
</li>
<li class="
">
<a class="page"
href="todomvc.html"
title="This guide walks through building a slightly modified version of TodoMVC with CanJS's Core libraries and can-fixture. It takes about 1 hour to complete.">
TodoMVC Guide
</a>
</li>
<li class="
">
<a class="page"
href="atm.html"
title="This guide walks through building and testing an ATM application with CanJS's
Core libraries. It teaches how to do test driven development (TDD)
and manage complex state. It takes about 2 hours to complete.">
ATM Guide
</a>
</li>
<li class="
">
<a class="page"
href="setup.html"
title="CanJS is packaged in multiple ways so that it can fit into any development workflow. Learn how to setup CanJS in different environments.">
Setting up CanJS
</a>
</li>
</ul>
</li>
<li>
<span>commitment</span>
<ul>
<li class="
">
<a class="page"
href="api.html"
title="This page walks through how to use and understand CanJS's API documentation.">
API Guide
</a>
</li>
<li class="
">
<a class="page"
href="examples.html"
title="">
Examples
</a>
</li>
<li class="
">
<a class="page"
href="../roadmap.html"
title="Learn about CanJS's future plans and how we make them, and how you can influence them.">
Roadmap
</a>
</li>
<li class="
">
<a class="page"
href="../migrate-3.html"
title="">
Migrating to 3.0
</a>
</li>
</ul>
</li>
<li>
<span>contribute</span>
<ul>
<li class="
">
<a class="page"
href="contributing/bug-report.html"
title="Learn how to submit a bug report.">
Bug Report
</a>
</li>
<li class="
">
<a class="page"
href="contributing/code.html"
title="Learn how contribute a code change to CanJS.">
Code
</a>
</li>
<li class="
">
<a class="page"
href="contributing/documentation.html"
title="Learn how to improve CanJS's site and documentation.">
Documentation
</a>
</li>
<li class="
">
<a class="page"
href="contributing/evangelism.html"
title="Learn about resources that can help you spread the word about CanJS.">
Evangelism
</a>
</li>
<li class="
">
<a class="page"
href="contributing/feature-suggestion.html"
title="Learn how to suggest a feature.">
Feature Suggestion
</a>
</li>
<li class="
">
<a class="page"
href="contributing/releases.html"
title="Release and hosting information for CanJS maintainers.">
Releases
</a>
</li>
</ul>
</li>
</ul>
</li>
<li class="
">
<a class="page"
href="../can-core.html"
title="The best, most hardened and generally useful libraries in CanJS.">
Core
</a>
</li>
<li class="
">
<a class="page"
href="../can-ecosystem.html"
title="Useful libraries that extend or add important features to the core collection.">
Ecosystem
</a>
</li>
<li class="
">
<a class="page"
href="../can-infrastructure.html"
title="Utility libraries that power the core and ecosystem collection.">
Infrastructure
</a>
</li>
<li class="
">
<a class="page"
href="../can-legacy.html"
title="Former libraries that we still accept patches for, but are not under active development.">
Legacy
</a>
</li>
</ul>
</div>
</div>
<div id="right" class="column">
<div class="top-right">
<div class="top-right-top">
<ul class="top-right-bitovi">
<li class="dropdown">
<a href="http://bitovi.com" class="bitovi icon-bits">Bitovi</a>
<ul class="dropdown-menu">
<li><a href="http://bitovi.com">Bitovi.com</a></li>
<li><a href="http://bitovi.com/blog/">Blog</a></li>
<li><a href="http://bitovi.com/consulting/">Consulting</a></li>
<li><a href="http://bitovi.com/training/">Training</a></li>
<li><a href="http://bitovi.com/open-source/">Open Source</a></li>
</ul>
</li>
</ul>
<div class="brand">
<div class="logo">
<a href="../../index.html" alt="CanJS"></a>
</div>
</div>
<ul class="top-right-links">
<li>
<a href="https://gitter.im/canjs/canjs">Chat</a>
</li>
<li>
<a href="http://forums.donejs.com/c/canjs">Forum</a>
</li>
<li>
<a class="github-button nav-social" href="https://github.com/canjs/canjs" data-count-href="/canjs/canjs/stargazers" data-count-api="/repos/canjs/canjs#stargazers_count">Star</a>
</li>
<li>
<a href="https://twitter.com/canjs" class="twitter-follow-button nav-social" data-show-count="true" data-show-screen-name="false">Follow @canjs</a><script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</li>
</ul>
</div>
<div class="breadcrumb">
<li><a href="../../index.html">CanJS</a></li> /
<li><a href="../guides.html">Guides</a></li> /
<li><a href="mission.html">Mission</a></li>
<li class="breadcrumb-dropdown">/ <a> On this page</a>
<ul class="on-this-page"></ul>
</li>
<div class="nav-toggle" title="Back to top"></div>
</div>
</div>
<div class="bottom-right">
<article>
<section class="title">
<div class="page-type">
<h1>Mission</h1>
<div>page</div>
</div>
<section class="description">
<p>Learn about CanJS's mission, why it matters, and how we've worked (and will keep working) to accomplish it.</p>
</section>
</section>
<section class="on-this-page-table">
</section>
<section class="title-footer">
<ul class="title-links">
<!-- <li><a href="#">docco</a></li> -->
<li><a href="//github.com/canjs/canjs/tree/v3.0.0/docs/can-guides/introduction/mission.md">source</a></li>
<!-- <li><a href="#">download</a></li> -->
<!-- <li><a href="#">tests</a></li> -->
</ul>
</section>
<section class="body">
<p>CanJS's mission is to <strong>minimize the cost of building and maintaining
JavaScript applications by balancing innovation and stability, helping developers transcend a changing technology landscape</strong>.</p>
<p>You shouldn't have to rewrite your application to keep pace with technology.
So we constantly integrate new ideas and evolving best practices into CanJS libraries,
but in a responsible way that makes possible to
upgrade gracefully. We aim to provide a stable
and innovative platform, so you can block out noise and stay focused your app, not the tools.</p>
<p><img
srcset="../../docs/images/home/Home-Tortoise-color.png 1x, ../../docs/images/home/Home-Tortoise-color-x2.png 2x"
src="../../docs/images/home/Home-Tortoise-color.png"
style="float:right; padding-right: 40px;"/>
<img
srcset="../../docs/images/home/Home-Hare-color.png 1x, ../../docs/images/home/Home-Hare-color-x2.png 2x"
src="../../docs/images/home/Home-Tortoise-color.png" style="padding-left: 40px;"/></p>
<p>Keep reading to learn why our mission is important
and how we've fared in realizing it:</p>
<ul>
<li><a href="#Stabilityandinnovationmatter">Stability and innovation matter</a> - Why stability and innovation are the two most important factors in minimizing the cost of building and maintaining JavaScript Applications.</li>
<li><a href="#StabilityisdifficultintheJavaScriptcommunity">Stability is difficult in the JavaScript community</a> - Why the JavaScript community sees a never-ending stream of frameworks and suffers from <em>JavaScript Framework Fatigue</em>.</li>
<li><a href="#Ourhistoryofstabilityandinnovation">Our history of stability and innovation</a> - How we've managed to
keep innovating for almost 10 years while still providing a viable upgrade path, and what we're doing now to make CanJS even more stable moving forward.</li>
</ul>
<h2>Stability and innovation matter</h2>
<p>Stability and innovation are often conflicting goals but they are both critical
factors to application success. Application development lifecycles
can last years, so it's important that code written today will be relevant
tomorrow. Yet technology changes quickly, especially in JavaScript.
New technology brings better techniques and is critical for developer happiness
and retention.</p>
<p>When starting a new application, it's easy to forget that the majority of development happens after
the application is released. Many frameworks, after a short period of popularity, either:</p>
<ul>
<li>End up getting replaced by a new <em>hot</em> framework.</li>
<li>Release a major version that not even <em>remotely</em> backwards compatible with the previous version.</li>
</ul>
<p>Productivity-wise, over the life of your application, that ends up looking like this:</p>
<p><img src="../../docs/can-guides/images/introduction/betting-bomb-2.png" style="width:100%;max-width:650px"/></p>
<p>Or like this:</p>
<p><img src="../../docs/can-guides/images/introduction/betting-bomb.png" style="width:100%;max-width:650px"/></p>
<p>What is needed is a balance of innovation and stability, where developer productivity
increases over time, but doesn't take large steps backward. That looks something like:</p>
<p><img src="../../docs/can-guides/images/introduction/good-bet.png" style="width:100%;max-width:650px"/></p>
<p>This is our mission.</p>
<h2>Stability is difficult in the JavaScript community</h2>
<p>You may be familiar with the
<a href="https://medium.freecodecamp.com/javascript-fatigue-fatigue-66ffb619f6ce#.n5tt0jqhf">never-ending stream</a> of <a href="http://www.allenpike.com/2015/javascript-framework-fatigue/">hot new JavaScript frameworks</a>
that take our community by storm in approximately 1 to 2 year cycle.</p>
<blockquote>
<p>SproutCore -> Knockout -> Backbone -> Angular -> React -> ?</p>
</blockquote>
<p>This isn't surprising. Consider how many different programming languages you can use
on the server-side: Java, Ruby, Python, C#, Haskell, etc. There is only one JavaScript. Innovation
is going to move at a blistering pace. We should embrace it.</p>
<p>But, the blistering pace of innovation also means that most frameworks will emerge with one
revolutionary feature, and then fade as the
next revolutionary framework emerges. Instead of the old framework adopting new ideas, the community and its attention move onto the new <em>hot</em> framework.</p>
<p>This makes it difficult to avoid stagnation in any community driven tool over a long period of time.</p>
<h2>Our history of stability and innovation</h2>
<p>CanJS has been helping developers transcend the <a href="https://hackernoon.com/how-it-feels-to-learn-javascript-in-2016-d3a717dd577f#.lrntx9nby">constantly changing technology landscape</a>
for over 10 years. Read on to learn about:</p>
<ul>
<li>Our history of stability.</li>
<li>Our history of innovation.</li>
<li>How 3.0 improves stability and innovation.</li>
</ul>
<h3>Our history of stability</h3>
<p>CanJS has been around since 2007. CanJS was originally called <a href="http://javascriptmvc.com">JavaScriptMVC</a>. In 2012, JavaScriptMVC was split up into several pieces, including CanJS. Every year, we have improved CanJS by incorporating new best practices and ideas from the larger JavaScript community, while not leaving behind our existing users. The result has been a viable upgrade path for over 10 years!</p>
<p><img src="../../docs/can-guides/images/introduction/best-bet.png" style="width:100%;max-width:650px"/></p>
<p>Major releases are not fully backwards compatible, but it was possible to transition with
limited effort.</p>
<p>Lets see how one piece of CanJS, <a href="../can-control.html" title="Create organized, memory-leak free, rapidly performing, stateful controls with declarative event binding. Use Control to create UI
controls like tabs, grids, and context menus,
and organize them into higher-order business rules with
can.route. It can serve as both a traditional view and a traditional controller.">can-control</a>, evolved over this time.</p>
<p><strong>In 2007</strong>, using JavaScriptMVC 1.0, to listen to when any element
that matches the selector <code>.todos li.complete</code> is clicked, you might have written something like the following:</p>
<pre><code class="language-js">new MVC.Controller('todos',{
"li.complete click": function(el, ev){
// DO STUFF
}
});
</code></pre>
<p>JavaScriptMVC was one of the first libraries to support event delegation.
But these these old controls were not extensible, and couldn't work in a isolated
context.</p>
<p><strong>In 2009</strong>, <a href="http://jquery.com">jQuery</a> began to dominate JavaScript development.
We helped add event delegation to jQuery, and integrated it into JavaScriptMVC 2.0.
The previous code became:</p>
<pre><code class="language-js">$.Controller.extend("TodosController",{
"li.complete click": function(el, ev){
// DO STUFF
}
});
$(".todos").todos_controller();
</code></pre>
<p>In 2012, using CanJS 1.0, this became:</p>
<pre><code class="language-js">TodosController = can.Control.extend({
"li.complete click": function(el, ev){
// DO STUFF
}
});
new TodosController(".todos");
</code></pre>
<p><strong>In 2013</strong>, we released CanJS 2.0, and transitioned to
<a href="../can-component.html" title="Create a custom element that can be used to manage widgets or application logic.">can-component</a>s instead of <a href="../can-control.html" title="Create organized, memory-leak free, rapidly performing, stateful controls with declarative event binding. Use Control to create UI
controls like tabs, grids, and context menus,
and organize them into higher-order business rules with
can.route. It can serve as both a traditional view and a traditional controller.">can-control</a>s. But even now, almost 10 years later,
to make that <code>MVC.Controller</code> work in CanJS 3.0,
you could update it to the following:</p>
<pre><code class="language-js">var Control = require("can-control");
var TodosController = Control.extend({
"li.complete click": function(el, ev){
// DO STUFF
}
});
new TodosController(document.querySelector(".todos"));
</code></pre>
<p>This is one of many examples of CanJS's code undergoing significant
improvements and changes, while still keeping it possible to upgrade your application.</p>
<p>For teams upgrading to <code>3.0</code>, we created multiple <a href="../migrate-3.html" title="">migration paths</a>
so upgrading can be done incrementally.</p>
<h3>Our history of innovation</h3>
<p>Over the past 9 years of CanJS, the web has evolved, and the best practices in JavaScript application development have changed. As these changes have occurred, CanJS has filtered out the very best ideas and practices, and implemented them in evolving APIs.</p>
<p>To name a few:</p>
<ul>
<li>Event delegation became a best practice for managing events around 2009. CanJS added support for event delegation in 2008, before jQuery landed support. Later, when jQuery became ubiquitous, we
integrated jQuery into CanJS.</li>
<li>RESTful APIs eventually became the best practice for designing a backend interface. [can-model] in 2010 provided ActiveRecord style abstractions around this pattern.</li>
<li>Data bindings hit the mainstream in 2013 when Angular rose in popularity. CanJS landed support for this feature in 2011 with <a href="../can-ejs.html" title="EJS provides live ERB-style client-side templates.">can-ejs</a>.</li>
<li>Building UI widgets as HTML custom elements, similar to web components, has become a best practice. <a href="../can-component.html" title="Create a custom element that can be used to manage widgets or application logic.">can-component</a> landed in 2013 to support this architecture.</li>
<li>In 2015, CanJS landed support for using a Virtual DOM and simple server-side rendering with <a href="../can-vdom.html" title="A browser-lite environment for Node.js or a worker thread.">can-vdom</a>.</li>
<li>In 2016, CanJS added real-time support and advanced caching technology with <a href="../can-connect.html" title="can-connect provides persisted data middleware. Use it to assemble powerful model layers for any JavaScript project.">can-connect</a>.</li>
<li>In 2017, CanJS added a more powerful <a href="../can-define.html" title="Exports the define method that defines observable properties and their behavior on a prototype object.">observable type</a> and enabled it to use
<a href="can-define-stream">functional reactive programming techniques</a>.</li>
</ul>
<p>This timeline shows more examples:</p>
<iframe src="https://cdn.knightlab.com/libs/timeline/latest/embed/index.html?source=1lBdurIQbbJkTZ8_kCQaXZtFaD06ulMFAlkqyEmXH4k0&font=Bevan-PotanoSans&maptype=toner&lang=en&start_at_slide=3&height=650&start_zoom_adjust=-2" width="100%" height="650" style="max-width:800px" frameborder="0"></iframe>
<h3>How 3.0 improves stability and innovation</h3>
<p>CanJS 3.0 has been re-organized into several different dozen independent repositories,
each with it’s own npm package and version number using <a href="http://semver.org/">Semantic Versioning</a>.
Organizing CanJS into individual repositories will improve
CanJS's stability and innovation going forward.</p>
<h4>Stability</h4>
<p>Independent repositories improve stability because upgrades will
be easier and more frequent. For example,
compare upgrading a 2.3 app to upgrading a 3.0 app.</p>
<p>Despite making relatively few breaking changes, and
providing a <a href="../migrate-3.html" title="">migration guide</a>, upgrading from CanJS 2.3 to 3.0 looks like
a big step:</p>
<p><img src="../../docs/can-guides/images/introduction/mission-stability-3-upgrade.png" style="width:100%;max-width:400px"/></p>
<p>But if you break that step down, CanJS 2.3 is mostly CanJS 3.0 with a bunch of bug
fixes, a heap of new features, and a few breaking changes. Most of the difficulty
upgrading are the breaking changes, which account for the majority of the upgrade step size:</p>
<p><img src="../../docs/can-guides/images/introduction/mission-stability-upgrade-breakdown.png" style="width:100%;max-width:400px"/></p>
<p>Currently, to get all of those bug fixes and new features, you have to
take on those breaking changes all at once. Depending on your company culture,
and scale of your application, this might not be easy.</p>
<p>Going forward in CanJS 3.0, packages are released independently of
each other. You can upgrade to bug fixes and new features
immediately and delay breaking changes (exampe: <code>can-route@4.0.0</code>) until later. You can upgrade breaking changes in steps too. For example,
you might upgrade to <code>can-route@4.0.0</code> one month and <code>can-component@4.0.0</code>
the following month. CanJS 3.0's upgrade path might look like:</p>
<p><img src="../../docs/can-guides/images/introduction/mission-stability-upgrade-new.png" style="width:100%;max-width:450px"/></p>
<p>Independent repositories also means that <a href="../can-legacy.html" title="Former libraries that we still accept patches for, but are not under active development.">legacy</a> libraries, like <a href="../can-ejs.html" title="EJS provides live ERB-style client-side templates.">can-ejs</a> can continue
living through community driven fixes and releases. It doesn't die simply because
it's no longer included in the core CanJS build.</p>
<h4>Innovation</h4>
<p>Independent repositories enable CanJS to innovate faster for several reasons:</p>
<ul>
<li>Supporting <a href="../can-legacy.html" title="Former libraries that we still accept patches for, but are not under active development.">legacy</a> libraries, like <a href="../can-ejs.html" title="EJS provides live ERB-style client-side templates.">can-ejs</a>, will not slow down the
development of other libraries.</li>
<li>Experiments like <a href="../can-stream.html" title="Convert observable values into streams. Kefir is used internally to provide the stream functionality.">can-stream</a>, where a lot of innovation happens, can be
released and have breaking changes without having to "get in" breaking changes
in core and infrastructure libraries.</li>
<li>CanJS doesn't feel as monolithic, appealing to developers using
just one part. More users means more contributors.</li>
</ul>
<p>The shift to independent repositories was CanJS 3.0's biggest undertaking and
arguably biggest feature. This fact underscores how important our goal
of balancing innovation and stability is to us. For more nuts-and-bolts features of CanJS,
please read <a href="technical.html" title="">CanJS's Technical Highlights</a>.</p>
</section>
<script type="text/javascript">
var docObject = {"src":{"path":"docs/can-guides/introduction/mission.md"},"description":"Learn about CanJS's mission, why it matters, and how we've worked (and will keep working) to accomplish it.\n\n\n","name":"guides/mission","title":"Mission","type":"page","parent":"guides/introduction","order":2,"comment":" ","pathToRoot":"../.."};
</script>
</article>
<footer><p>CanJS is part of <a href="http://donejs.com" target="_blank">DoneJS</a>. Created and maintained by the core <a href="https://donejs.com/About.html#section=section_Team" target="_blank">DoneJS team</a> and <a href="http://bitovi.com" target="_blank">Bitovi</a>. <strong>Currently 3.0.0.</strong></p></footer>
</div>
</div>
</div>
<script>
steal = {
instantiated: {
"bundles/bit-docs-site/static.css!$css" : null
}
};
</script>
<script type='text/javascript' data-main="bit-docs-site/static" src="../static/node_modules/steal/steal.production.js"></script>
<script async defer src="https://buttons.github.io/buttons.js"></script>
</body>
</html>