---
title: Tutorial: Automate Your Upgrade to CanJS 3 with can-migrate
description: Learn how easy it is to use can-migrate and codemod scripts to automate most of your upgrade from CanJS 2 to CanJS 3!
image: https://www.bitovi.com/hubfs/canjs-background-blue-2.gif
---

- ![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

 August 15, 2017

# Tutorial: Automate Your Upgrade to CanJS 3 with can-migrate

 Learn how easy it is to use can-migrate and codemod scripts to automate most of your upgrade from CanJS 2 to CanJS 3!

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

In this tutorial, we will migrate a [CanJS](https://canjs.com/) app to CanJS 3 using [can-migrate](https://www.npmjs.com/package/can-migrate), a CLI codebase refactoring tool that automates a large portion of the work required to upgrade a 2.x codebase to CanJS 3.

Before getting started, I recommend reviewing the [migration guide](https://canjs.com/doc/migrate-3.html) to understand what changes are required for CanJS 3, as well as the [recommended migration process steps](https://canjs.com/doc/guides/upgrade/using-codemods.html#RecommendedMigrationProcess) to learn about the process we’ll follow in this tutorial.

You can also watch this YouTube video to follow along with what’s in this tutorial:

## Get Started

We will use the [CanJS chat repo](https://github.com/canjs/chat) in this tutorial. You can [clone it](https://help.github.com/articles/cloning-a-repository/) and follow along or use your own CanJS 2 project.

In this section, we will prepare for the migration by installing `can-migrate`, creating a `migration` branch in git, and ensuring all the tests are passing.

### Install, Branch, and Test

First, install the `can-migrate` CLI globally:

```
npm install -g can-migrate
```

Create a branch in the repo for the migration and make sure the tests pass:

```
git checkout -b migration
npm test
```

![pasted image 0.png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200.png?width=476&height=423&name=pasted%20image%200.png)

Now that all the tests passing on the `migration` branch, in the next section let’s run `can-migrate` on some of the tested JavaScript files.

## Migration Process

In the chat codebase, we have the `main.js` file as well as three testable folders: `src/home`, `src/message`, and `src/models`. For each of these, we need to do the following:

1. Run `can-migrate` on each directory and the `main.js` file
2. Install the necessary `can-` packages added to the code by `can-migrate`
3. Remove global imports of the `can` library
4. Re-run the tests
5. Fix issues if the tests aren’t passing

### Run can-migrate

Run `can-migrate` on your first directory by passing the directory and the `--apply` flag to the CLI:

```
can-migrate src/models/ --apply
```

`can-migrate` works by running [transform scripts](https://canjs.com/doc/guides/upgrade/using-codemods.html#IntroductiontotheTransformScripts) that parse source code in order to do a code-aware find-and-replace refactor across multiple files. The command above will run all of the transforms on all the JavaScript files in the `src/models/` directory. You know it is working when you see it running like this:

![migration-models=v3.gif](https://www.bitovi.com/hs-fs/hubfs/migration-models=v3.gif?width=554&height=514&name=migration-models=v3.gif)

### What changed?

After we let `can-migrate` do its magic, let’s investigate what changed. First, let’s take a look at the diff:

![pasted image 0 (1).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(1).png?width=576&height=527&name=pasted%20image%200%20(1).png)

Here are the transform scripts that made changes and what they did:

1. [can-list/replace.js](https://github.com/canjs/can-migrate/blob/master/lib/transforms/can-list/replace.js) 
     - Added import statement: `import CanList from "can-list"`
     - Updated references of `can.List` to `CanList`
2. [can-map/replace.js](https://github.com/canjs/can-migrate/blob/master/lib/transforms/can-map/replace.js) 
     - Added import statement: `import CanMap from "can-map"`
     - Updated references of `can.Map` to `CanMap`
3. [can-map-define/import.js](https://github.com/canjs/can-migrate/blob/master/lib/transforms/can-map-define/import.js) 
     - Updated import statement from nested path `"can/map/define/define"` to `"can-map-define"`

Learn more about what each transform does in the [Complete List of Transform Scripts](https://canjs.com/doc/guides/upgrade/using-codemods.html#CompleteListofTransformScripts).

### Install the can-* packages

As we saw above, `can-migrate` added import statements for three new packages to the top of the `model/message.js` file: `can-list`, `can-map`, and `can-map-define`. In the next step, we will install these packages and make sure they are saved in our `package.json`.

Use npm to install the modules that were imported by `can-migrate`:

```
npm install can-list can-map can-map-define --save
```

### Remove the can global dependency

You may have noticed that in the diff above that we are importing the `can-` modules but we did not remove the global `can` import: `import can from "can";`. In this step, delete that line.

![pasted image 0 (3).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(3).png?width=720&height=209&name=pasted%20image%200%20(3).png)

### Re-run Tests

Next, re-run your tests to see if there are any issues that need to be fixed:

```
npm test
```

![pasted image 0 (4).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(4).png?width=691&height=561&name=pasted%20image%200%20(4).png)

Luckily for us, all the tests are passing without any need to manual intervention.

## Repeat

Now we’ll repeat the [migration process](https://www.bitovi.com/blog/tutorial-automate-your-upgrade-to-canjs-3-with-can-migrate#migration-process) on the rest of our [modlets](https://www.bitovi.com/blog/modlet-workflows) and JavaScript files, install the new packages, remove the `can` package, ensure the tests are still passing, and manually refactor if needed.

### Home Modlet Migration

After running:

```
can-migrate src/home/ --apply
```

It made the following changes, as highlighted in this diff:

![pasted image 0 (5).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(5).png?width=527&height=482&name=pasted%20image%200%20(5).png)

We installed `can-map` and `can-map-define` in a previous step, so all we need to install is the `can-component` package. After that, we’ll re-run the tests to make sure they’re all still passing:

```
npm install can-component --save
npm test
```

### Messages Modlet Migration

After running:

```
can-migrate src/messages/ --apply
```

It made the following changes, as highlighted in this diff:

![pasted image 0 (6).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(6).png?width=596&height=548&name=pasted%20image%200%20(6).png)

Since we are using object assignment destructuring on the second to last line, we are going to get an error because we import our `messages.stache` template as `template`, but the component is expecting the variable to be named `view`.

![pasted image 0 (7).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(7).png?width=549&height=213&name=pasted%20image%200%20(7).png)

After changing that, our tests will pass!

```
npm test
```

![pasted image 0 (8).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(8).png?width=503&height=414&name=pasted%20image%200%20(8).png)

### Main.js Migration

After running:

```
can-migrate src/main.js --apply
```

It made the following changes, as highlighted in this diff:

![pasted image 0 (9).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(9).png?width=542&height=581&name=pasted%20image%200%20(9).png)

It added an import statement for the `can-route` package, so we need to install it. Don't forget to test it before moving on to the next section:

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

Next, we need to remove the last use of the `can` module in this file. Right now, `can.$` is used to access jQuery; in the next section, we’ll talk about what this is and how we can migrate that code.

#### can.$

Previous versions of CanJS shipped with your DOM manipulation library of choice. jQuery was the most popular library used and it was made available to your app via `can.$`.

CanJS 3 does not depend on any external library. In our app, we can migrate from `can.$` to standalone `$` with the following steps:

1. Import jQuery at the top of the file:  
   `import $ from ‘jQuery’`
2. Change `can.$` to just `$`: 
     - Before: `can.$("body").append(template(appState));`
     - After: `$("body").append(template(appState));`
3. Remove the global `can` import

See the example diff below for the `main.js` file:

![pasted image 0 (11).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(11).png?width=611&height=374&name=pasted%20image%200%20(11).png)

#### Re-run Tests

Last, we’ll re-run the tests to make sure everything is passing:

```
npm test
```

All the tests are passing! We’re almost done with the entire upgrade.

![pasted image 0 (10).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(10).png?width=470&height=450&name=pasted%20image%200%20(10).png)

## Remove can 2.3 from project

If you haven’t already, remove all the global `can` imports and the global `can` dependency from your `package.json` file:

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

In the chat application, we had to manually remove the global import from `src/models/message.js` and `src/main.js`. The `npm uninstall` command above removed `can` from the `package.json`. Don’t forget to re-run your tests one last time to ensure everything is still in working order.

![pasted image 0 (12).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(12).png?width=611&height=662&name=pasted%20image%200%20(12).png)

### Fix issues that arise from removing can 2.3

After uninstalling `can`, we found an error coming from stealJS:

![pasted image 0 (16).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(16).png?width=720&height=112&name=pasted%20image%200%20(16).png)

This error is because we use both steal and stache in this project so in CanJS 3, we need to install `steal-stache`.

```
npm install steal-stache@3 --save
```

Next, we found another error because we were using an old version of `bit-tabs`, which we need to upgrade as well:

![pasted image 0 (17).png](https://www.bitovi.com/hs-fs/hubfs/pasted%20image%200%20(17).png?width=720&height=96&name=pasted%20image%200%20(17).png)

```
npm install bit-tabs@latest --save
```

With that, the tests pass and our migration is complete! Congratulations!

## Upgrade today

You can look at the [detailed diff across versions](https://github.com/canjs/chat/compare/canjs-2.3%E2%80%A6canjs-3.0) to get an overview of the changes to the chat codebase after running `can-migrate` on each modlet and JavaScript file.

The [Using Codemods guide](https://canjs.com/doc/guides/upgrade/using-codemods.html) has all the information you’ll need to use `can-migrate` to upgrade your app to CanJS 3. You can also find more details about all the steps required in the [migration guide](https://canjs.com/doc/migrate-3.html).

If you have an issue with using `can-migrate`, please [create an issue on GitHub](https://github.com/canjs/can-migrate/issues/new). You can also [contribute](https://canjs.com/doc/guides/contribute.html) back to the project by looking at the [open issues](https://github.com/canjs/can-migrate/issues) and commenting on any you’d like to help fix.

If you have any questions about migrating, please post in our [forums](http://forums.donejs.com/c/stealjs) or [Gitter chat](https://gitter.im/stealjs/steal) and we’ll be happy to help!

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

 Previous Post

![](https://www.bitovi.com/hs-fs/hubfs/Banner_Images/banner-create-lsg-part-3.png?height=117&name=banner-create-lsg-part-3.png) [ Tutorial Part 3: Documenting a Stylesheet in a Living Style Guide ](https://www.bitovi.com/blog/documenting-a-stylesheet-in-a-living-style-guide)

  

 Next Post

![donejs-banner.jpg](https://www.bitovi.com/hs-fs/hubfs/donejs-banner.jpg?height=117&name=donejs-banner.jpg) [ August 2017 DoneJS Community Update ](https://www.bitovi.com/blog/august-2017-donejs-community-update)

```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/tutorial-automate-your-upgrade-to-canjs-3-with-can-migrate",
    "@type" : "WebPage",
    "description" : "Learn how easy it is to use can-migrate and codemod scripts to automate most of your upgrade from CanJS 2 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" : "The Bitovi Team"
  },
  "dateModified" : "August 15, 2017, 1:00:13 PM",
  "datePublished" : "2017-08-15 13:00:00",
  "description" : "Learn how easy it is to use can-migrate and codemod scripts to automate most of your upgrade from CanJS 2 to CanJS 3!",
  "headline" : "Tutorial: Automate Your Upgrade to CanJS 3 with can-migrate",
  "image" : {
    "@type" : "ImageObject",
    "url" : "https://www.bitovi.com/hubfs/canjs-background-blue-2.gif"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```