can.Component.extend() vs. other approaches

In the documentation I see different recipes and code examples implemented using:

  1. can.Component.extend()

  2. can.DefineMap.extend()

  3. Both of the above combined

  4. <script type="text/stache"> combined with can.DefineMap.extend()

It seems that #4 accomplishes what #1 alone does in other examples, but I’m not sure. It also seems as though #1 could be used for any of the above, but again I’m not sure.

Is there a benefit to using #2, #3, or #4, or could I just as well use #1 for all projects?


In general, I would always define a component and use it vs. create a text/stache script and render it with a view model.

In CanJS 4, we added the ability to upgrade an element that’s in the html to a component. Internally we call this auto-mounting, but I don’t think it’s a documented feature (it’s a by-product of CanJS components being backed by real custom elements). Some of our code examples haven’t been updated to take advantage of that, which is why you might see some recipes that show the “old” way.

The default type for a component’s ViewModel is a can-define/map/map, which is why you can just write ViewModel: { ... }. Just yesterday I opened a PR to make the docs a little more clear (feedback welcome):

That does clarify the issues some, but I’m still not sure if there is a reason not to go with #1 above for all projects. Is there?

Go with #1, like it’s shown in the Setting Up CanJS JS Bin:

  tag: "my-app",
  view: `
    {{#eq page 'home'}}
      <a href="{{routeUrl(page='home')}}">
  ViewModel: {
    page: "string"