---
title: How to Upgrade a DoneJS Plugin to CanJS 3
description: This article will show you how to upgrade an existing DoneJS plugin to CanJS 3.
image: http://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

 December 21, 2016

# How to Upgrade a DoneJS Plugin to CanJS 3

 This article will show you how to upgrade an existing DoneJS plugin to CanJS 3.

![Chasen Le Hara](https://app.hubspot.com/settings/avatar/47447d7b410651534d079d84497c1a5c)

 Chasen Le Hara

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=)

CanJS 3 has been [released](https://www.bitovi.com/blog/canjs-3-0-release)! It’s a major new version with some breaking changes, but our [migration guide](http://canjs.com/doc/migrate-3.html) has everything you need to upgrade your app or plugin today.

The migration guide breaks the upgrade process up into five steps:

1. [Pre-migration preparation](http://canjs.com/doc/migrate-3.html#Pre_migrationpreparation) you can do in your current 2.x project to more easily move to 3.x in the future.
2. [The minimal migration path](http://canjs.com/doc/migrate-3.html#Minimalmigrationpath), which includes the fewest changes required to upgrade from 2.x to 3.x.
3. [The modernized migration path](http://canjs.com/doc/migrate-3.html#Modernizedmigrationpath), which includes upgrading your code to match more modern conventions (such as using the new npm packages).
4. [The latest & greatest migration path](http://canjs.com/doc/migrate-3.html#Latest_greatestmigrationpath), which uses all of the modern libraries we are most excited about (such as [can-define](http://canjs.com/doc/can-define.html)).
5. [How to avoid future deprecations and removals](http://canjs.com/doc/migrate-3.html#Avoidfuturedeprecations_removals) in releases after 3.x

In a [previous blog post](https://www.bitovi.com/blog/create-reusable-components-for-your-donejs-applications), we made [a reusable DoneJS plugin](https://github.com/donejs/donejs-number-input). It already follows the best practices from CanJS 2.3 and doesn’t use any features that might be deprecated or removed in the future, so in this post, we’re going to follow the middle three upgrade steps to make our plugin ready for the future.

## Minimal migration path

First, we’re going to run the following command to install the latest version of CanJS and save it to our `package.json`:

```
npm install can --save
```

This will change our `package.json` to use something like `^3.3.0` instead of `^2.3.0`.

Next, we’ll install [steal-stache](http://canjs.com/doc/steal-stache.html) so our templates can be imported.

```
npm install steal-stache --save
```

This will add `steal-stache` to our `package.json`.

Now, when we run `npm test`, we’ll see all five tests passing. Success!

Those two steps really are the only things we need to do for our plugin. Depending on which CanJS 2.3 features your plugin uses, you might need to follow some of the other steps in the migration guide.

## Modernized migration path

You can set your project up for easier upgrades in the future by using the independent CanJS modules (instead of the main `can` package).

First, we’ll need to search for any uses of the `can` package. We can do this pretty easily with `grep`:

```
grep --exclude-dir={dist,node_modules} -R "can/" .
```

This returns the following:

```
./src/donejs-number-input.html:        main="can/view/autorender/">
./src/donejs-number-input.js:import Component from 'can/component/';
./src/donejs-number-input.js:import Map from 'can/map/';
./src/donejs-number-input.js:import 'can/map/define/';
```

The [migration guide lists](http://canjs.com/doc/migrate-3.html#Modernizedmigrationpath) all of the 2.3 module paths that can be replaced with new modules.

| Before | After |
| --- | --- |
| `can/component/` | `can-component` |
| `can/map/` | `can-map` |
| `can/map/define/` | `can-map-define` |
| `can/view/autorender/` | `can-view-autorender` |

This tells us which modules we need to install:

```
npm install can-component can-map can-map-define can-view-autorender --save
```

Now we can replace the first three lines in `src/donejs-number-input.js`:

```
import Component from 'can/component/';
import Map from 'can/map/';
import 'can/map/define/';
```

With:

```
import Component from 'can-component';
import Map from 'can-map';
import 'can-map-define';
```

Similarly, in `donejs-number-input.html`, we’ll replace:

```
<script src="../node_modules/steal/steal.js"
        main="can/view/autorender/"></script>
```

With:

```
<script src="../node_modules/steal/steal.js"
        main="can-view-autorender"></script>
```

Now we can uninstall the main `can` package:

```
npm uninstall can --save
```

Now, when we run `npm test`, we’ll see all five tests passing. Success!

Again, the migration guide has additional steps you can follow, depending on which CanJS 2.3 features your plugin uses.

## Latest & greatest migration path

Our upgrade looks great so far, but we can make our plugin take advantage of all of CanJS 3’s awesomeness by moving from the legacy `can-map` module to `can-define`.

First, let’s install `can-define`:

```
npm install can-define --save
```

Next, we’re going to start modifying the `src/donejs-number-input.js` file.

Let’s start by replacing these lines:

```
import Map from 'can-map';
import 'can-map-define';
```

With:

```
import DefineMap from 'can-define/map/';
```

You’ll notice that we went from two lines down to one; `can-define/map/` has the define functionality we want built in.

Next, let’s update our view model to use the new module, move the properties out of the `define` property, and drop our use of `attr`. Replace:

```
export const ViewModel = Map.extend({
  define: {
    value: {
      value: 0,
      type: 'number',
      set(value) {
        if(value > this.attr('max')) {
          return this.attr('max');
        }
        
        if(value < this.attr('min')) {
          return this.attr('min');
        }
        
        return value;
      }
    },
    max: {
      value: Number.MAX_VALUE,
      type: 'number'
    },
    min: {
		value: 0,
		type: 'number'
	}
  },
  
  increment() {
    this.attr('value', this.attr('value') + 1);
  },
	
  decrement() {
    this.attr('value', this.attr('value') - 1);
  }
});
```

With:

```
export const ViewModel = DefineMap.extend({
  value: {
    value: 0,
    type: 'number',
    set(value) {
      if(value > this.max) {
        return this.max;
      }

      if(value < this.min) {
        return this.min;
      }

      return value;
    }
  },
  max: {
    value: Number.MAX_VALUE,
    type: 'number'
  },
  min: {
    value: 0,
    type: 'number'
  },

  increment() {
    this.value = this.value + 1;
  },

  decrement() {
    this.value = this.value - 1;
  }
});
```

There might be other uses of `.attr()` in our code, so let’s use grep again to find them:

```
grep --exclude-dir={dist,node_modules} -R ".attr(" .
```

This returns the following:

```
./src/donejs-number-input_test.js:  QUnit.equal(vm.attr('value'), 0, 'Default value is 0');
./src/donejs-number-input_test.js:  QUnit.equal(vm.attr('max'), Number.MAX_VALUE, 'Max value is number max value');
./src/donejs-number-input_test.js:	QUnit.equal(vm.attr('min'), 0, 'Max value is number max value');
./src/donejs-number-input_test.js:  QUnit.equal(vm.attr('value'), 1, 'Value incremented');
./src/donejs-number-input_test.js:  QUnit.equal(vm.attr('value'), 1, 'Value updated');
```

We’ll need to make these replacements:

| Before | After |
| --- | --- |
| `vm.attr('max')` | `vm.max` |
| `vm.attr('min')` | `vm.min` |
| `vm.attr('value')` | `vm.value` |

After those replacements have been made, we can uninstall the `can-map` and `can-map-define` packages:

```
npm uninstall can-map can-map-define --save
```

Now, when we run `npm test`, we’ll see all five tests passing. Success!

Depending on which CanJS features you’re using, there are [more steps](http://canjs.com/doc/migrate-3.html#Latest_greatestmigrationpath) you can take to take advantage of everything CanJS 3 has to offer.

## Migrate today

The [migration guide](http://canjs.com/doc/migrate-3.html) is a great resource for moving your DoneJS plugin to CanJS 3 today. In it, you’ll find all of the information that was used in this blog post, and more!

You can also see the commits for each step of upgrading our example plugin:

1. [Minimal migration path](https://github.com/donejs/donejs-number-input/commit/31363e6d8183df7c4877b07f7e6a4206f03188e0)
2. [Modernized migration path](https://github.com/donejs/donejs-number-input/commit/fa7c0ae67b84523e905b6acf6ddc50ad31ce835c)
3. [Latest & greatest migration path](https://github.com/donejs/donejs-number-input/commit/728a1b8f5953f15f4f60d6fc3b96d8c713572b29)

If you have any questions about migrating, please post in our [forums](http://forums.donejs.com/c/canjs) or [Gitter chat](https://gitter.im/canjs/canjs)!

[![Tag for open source](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) open source ](https://www.bitovi.com/blog/topic/open-source)[![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)

 Previous Post

![](https://www.bitovi.com/hs-fs/hubfs/canjs-background-blue-1.gif?height=117&name=canjs-background-blue-1.gif) [ CanJS 3.0 Release ](https://www.bitovi.com/blog/canjs-3-0-release)

  

 Next Post

![](https://www.bitovi.com/hs-fs/hubfs/stealbkg.png?height=117&name=stealbkg.png) [ StealJS 1.0 Release ](https://www.bitovi.com/blog/stealjs-1.0-release)

```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/how-to-upgrade-a-donejs-plugin-to-canjs-3",
    "@type" : "WebPage",
    "description" : "This article will show you how to upgrade an existing DoneJS plugin to CanJS 3."
  },
  "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" : "Chasen Le Hara"
  },
  "dateModified" : "December 21, 2016, 7:21:11 PM",
  "datePublished" : "2016-12-21 19:21:11",
  "description" : "This article will show you how to upgrade an existing DoneJS plugin to CanJS 3.",
  "headline" : "How to Upgrade a DoneJS Plugin to CanJS 3",
  "image" : {
    "@type" : "ImageObject",
    "url" : "http://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"
  }
}
```