---
title: DoneJS 3
description: DoneJS 3 provides best in class server-side rendering, tree-shaking builds, improved service-layer integration with can-query-logic, and more. Read on to learn what's included in this release.
image: https://www.bitovi.com/hubfs/donejs-banner.jpg
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting)
- ![Project Management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project Management](https://www.bitovi.com/services/agile-project-management-consulting)
- ![Product Design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product Design](https://www.bitovi.com/services/product-design-consulting)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting)
- [Design systems](https://www.bitovi.com/services/axure-figma-migration)
- [React](https://www.bitovi.com/services/frontend/react-consulting)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about delivering products and solving problems.
  
  ](https://www.bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships)
- [![Academy](https://www.bitovi.com/hubfs/icon%20-%20academy%20(4).svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse or contribute to our community
  
  ](https://www.bitovi.com/open-source)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

 January 8, 2019

# DoneJS 3

 DoneJS 3 provides best in class server-side rendering, tree-shaking builds, improved service-layer integration with can-query-logic, and more. Read on to learn what's included in this release.

![The Bitovi Team](https://www.bitovi.com/hubfs/TheBitoviTeam%20(1).png)

 The Bitovi Team

Share:

[![Twitter](https://www.bitovi.com/hubfs/limbo-generated/_astro/twitter-white.os3xLc3C_Z2nW4or.svg) ](https://twitter.com/intent/tweet?text=) [![Reddit](https://www.bitovi.com/hubfs/limbo-generated/imgs/icons/reddit.png) ](http://reddit.com/submit?url=)

DoneJS 3.0 is out! 🎆

If you're unfamiliar with DoneJS you should definitely check out [our homepage](https://donejs.com/) and run through the [getting started guide](https://donejs.com/Guide.html) (it doesn't take very long). Let me give you the quick spiel: DoneJS is a JavaScript framework that provides you everything you need to build performant real-time applications.

DoneJS 3.0 continues on that mission with:

- Dramatically faster production [time-to-interactive](https://developers.google.com/web/tools/lighthouse/audits/time-to-interactive) times thanks to [incremental rendering](https://donejs.com/Features.html#incremental-rendering).
- The latest from [CanJS](https://canjs.com/) [5.0](https://www.bitovi.com/blog/canjs-5), such as tree-shakable modules (no more need to import from a dozen or more different packages) and a more [easily configurable service layer](https://canjs.com/doc/guides/data.html).
- [StealJS](https://stealjs.com/) [2.0](https://www.bitovi.com/blog/steal-2.0), makes debugging easier by removing the promise polyfill when it's not needed, and adds support for tree-shaking (both in development and production builds)!

So settle in while we go over as much of what the new DoneJS version provides as we can cram into one article.

# Incremental rendering

About a year ago we started thinking about how we could incorporate streaming and [HTTP/2 into DoneJS](https://www.bitovi.com/blog/http2-in-donejs). DoneJS has long had the easiest to use server rendering solution of any framework. With streaming we asked; *how can we also make it the fastest*?

Our answer to this question is incremental rendering. Incremental rendering splits your app into two parts: the static content that can be sent right away, and the dynamic content that needs to be waited on.

By sending the static content immediately, it allows an app to start booting up earlier than in traditional SSR. Meanwhile the server continues to render that dynamic content and send deltas back to the client.

The result is the fastest server rendering solution on the market. See below, the app on the left is a traditional SSR app (using DoneJS 2) and the app on the right is using incremental rendering in DoneJS 3.

# CanJS 5

You can learn about everything that went into CanJS 5 in [its release article](https://www.bitovi.com/blog/canjs-5).  The following are some of the things that DoneJS 3 highlights in its generators and guides.

## can-debug

[can-debug](https://canjs.com/doc/can-debug.html) provides several methods for debugging the ways in which observable affect each other. The [CanJS Debugging Guide](https://canjs.com/doc/guides/debugging.html) gives you a primer on debugging CanJS applications.

Additional, can-debug enables the devtools that allow you to inspect the state of your ViewModel graphically. The [CanJS DevTools](https://chrome.google.com/webstore/detail/canjs-devtools/hhdfadlgplkpapjfehnjhcebebgmibcb) allow you to

- View and edit your ViewModels.
- Visualize the dependency graph of your components.
- Debug changes to observables using the CanJS queues system.

![49823678-41eb0d80-fd4e-11e8-8d0f-bb4bb7131502](https://user-images.githubusercontent.com/361671/49823678-41eb0d80-fd4e-11e8-8d0f-bb4bb7131502.png)

## Separating Route data from the Rest of the Application ViewModel

Sometimes there are things you want in your global state (The Application ViewModel) that you do not want bound to the route. Previously this required defining those properties as `serialize: false`.

In DoneJS 3 we no longer bind the Application ViewModel to the route. Instead, only a property on the ViewModel gets bound.

By default this is the `routeData` property. In your index.stache this gets declared like so:

 

```
<can-import from="~/app" export-as="viewModel" route-data="routeData" />
```

 

## The **pageComponent** pattern

One thing we've always noticed about DoneJS apps is that the switch statement in index.stache never quite felt right. Even in a small app like [place-my-order](http://www.place-my-order.com/) it becomes difficult to read.

In more complex apps it has been common to dynamically generic a stache template with can-imports to progressively load the current page.

Thanks to constructible [can-components](https://canjs.com/doc/can-component.html) and [can-value](https://canjs.com/doc/can-value.html) you can now do this easier in JavaScript.

Check out the place-my-order [Application ViewModel](https://github.com/donejs/place-my-order/blob/bfd1b07206f2a64c91252f4dfa792647fd6cb7ec/src/app.js) to see how this works. Here's a small snippet:

 

```
get pageComponent() {
  switch(this.routeData.page) {
    case 'home': {
      return steal.import('~/pages/home.component')
      .then(({default: Home}) => {

        return new Home();

      });
    }
    ...
  }
```

 

Which allows you to write this little stache:

 

```
{{ #if ( this.pageComponent.isResolved ) }}
  {{ this.pageComponent.value }}
{{ else }}
  {{# if ( this.pageComponent.isRejected ) }}
    <div>Error: {{ this.pageComponent.reason }}</div>
  {{ else }}
    <div class="loading"></div>
  {{/ if }}
{{/ if }}
```

 

What this does is:

- Showing a loading animation while the page component is being progressively loaded.
- Shows the page component once it has been loaded. `{{this.pageComponent.value}}`  inserts the component instance.
- Shows an error message if there was an error with loading the component.

# for/of

In stache you can now render items in a list using a [`for/of`](https://canjs.com/doc/can-stache.helpers.for-of.html) loop that works similar to that of JavaScript.

This continues efforts to make scope more readable in stache templates. If you stick to for/of loops you can always reference your component’s ViewModel with `this`.

 

```
{{# for( item of restaurant.menu.dinner ) }}
  <li class="list-group-item">
    <label>
      <input type="checkbox"
        on:change="this.order.items.toggle(item)"
        {{# if( this.order.items.has( item ) ) }}checked{{/ if }}>
      {{ item.name }} <span class="badge">${{ item.price }}</span>
    </label>
  </li>
{{/ for }}
```

 

# StealJS 2

Additionally DoneJS comes with StealJS 2 which gives you:

Native Promises

By default steal.js doesn’t include the Promise polyfill (it's available as **steal-with-promises.js** if you need it). This makes for a much better debugging experience in asynchronous code:

![49828671-7664c680-fd5a-11e8-8a60-059cf48542e3](https://user-images.githubusercontent.com/361671/49828671-7664c680-fd5a-11e8-8a60-059cf48542e3.png)

## Tree Shaking

Tree-shaking is a form of dead-code elimination that examines `import` statements to determine what code is used. Any code that's not used can be eliminated, or just never loaded.

StealJS is likely the first client-side module loader to provide tree-shaking. This allows DoneJS apps to import everything from **can**, rather than individual packages.

Your code goes from:

 

```
import DefineMap from 'can-define/map/map';
import DefineList from 'can-define/list/list';
import superModel from 'can-super-model';
import QueryLogic from 'can-query-logic';
```

 

To a more simple:

 

```
import { DefineMap, DefineList, superModel, QueryLogic } from 'can';
```

 

Thanks to tree-shaking we can include all of CanJS' ecosystem packages as well.

This means if you have a use case for streams you can just include `defineStreamKefir` in your import statement from **can**. No extra packages to install.

# Coming Up

DoneJS 3 brings a lot to the table but we aren’t slowing down. In 2019 we’ll put even more focus on improving the developer experience in DoneJS apps. First thing: [improving build times with **steal-tools build**](https://github.com/stealjs/steal-tools/issues/884).

And of course, what is voted on in the DoneJS Community Survey. Please [sign up](https://donejs.com/survey.html) to let us know what you want to see prioritized in the coming months.

## Hire us

DoneJS’s main sponsor is [Bitovi](https://www.bitovi.com/). We provide web and mobile application consulting services. We can [build your app](https://www.bitovi.com/development), [work with you to build it](https://www.bitovi.com/client-work), or [teach you how to build it](https://www.bitovi.com/training). To learn more visit [bitovi.com](https://www.bitovi.com/) or [@bitovi on Twitter](https://twitter.com/bitovi).

[![Tag for development](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) development ](https://www.bitovi.com/blog/topic/development)[![Tag for canjs](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) canjs ](https://www.bitovi.com/blog/topic/canjs)[![Tag for stealjs](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) stealjs ](https://www.bitovi.com/blog/topic/stealjs)[![Tag for donejs](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) donejs ](https://www.bitovi.com/blog/topic/donejs)

 Previous Post

![svg-typeface-featured](https://www.bitovi.com/hs-fs/hubfs/blogposts/creating-svg-typeface/svg-typeface-featured.png?height=117&name=svg-typeface-featured.png) [ Creating an SVG Icon Typeface ](https://www.bitovi.com/blog/creating-an-svg-icon-typeface)

  

 Next Post

![Juan’s meetup cropped darkened](https://www.bitovi.com/hs-fs/hubfs/Juan%E2%80%99s%20meetup%20cropped%20darkened.jpg?height=117&name=Juan%E2%80%99s%20meetup%20cropped%20darkened.jpg) [ Join Us for Our First Online Meetup ](https://www.bitovi.com/blog/join-us-for-our-first-online-meetup)

```json
{
  "@context" : "http://schema.org",
  "@type" : "Organization",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "Libertyville",
    "addressRegion" : "IL",
    "postalCode" : "60048",
    "streetAddress" : "1134 Pine Tree Lane "
  },
  "alternateName" : "Bitovi",
  "areaServed" : {
    "@type" : "GeoCircle",
    "geoMidpoint" : {
      "@type" : "GeoCoordinates",
      "latitude" : "41.8781",
      "longitude" : "87.6298"
    },
    "geoRadius" : "5000 km"
  },
  "description" : "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
  "email" : "contact@bitovi.com",
  "image" : "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
  "logo" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
  "mainEntityOfPage" : {
    "@id" : "https://www.bitovi.com/blog/donejs-3",
    "@type" : "WebPage",
    "description" : "DoneJS 3 provides best in class server-side rendering, tree-shaking builds, improved service-layer integration with can-query-logic, and more. Read on to learn what's included in this release."
  },
  "naics" : "541511",
  "name" : "Bitovi Web App Consulting",
  "sameAs" : [ "https://www.facebook.com/BitoviLLC/", "https://twitter.com/bitovi", "https://www.linkedin.com/company/bitovi" ],
  "telephone" : "312-620-0386",
  "url" : "http://bitovi.com"
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "The Bitovi Team"
  },
  "dateModified" : "January 8, 2019, 8:02:35 PM",
  "datePublished" : "2019-01-08 19:41:54",
  "description" : "DoneJS 3 provides best in class server-side rendering, tree-shaking builds, improved service-layer integration with can-query-logic, and more. Read on to learn what's included in this release.",
  "headline" : "DoneJS 3",
  "image" : {
    "@type" : "ImageObject",
    "url" : "https://www.bitovi.com/hubfs/donejs-banner.jpg"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```