What's the difference between custom components and custom elements?

I’m confused at what the differences are between custom components and custom elements. When I use the CLI generator to make one of each, they’re each composed of an html view and a JS/TS view-model and look extremely similar to one another:

Custom Element:

<template>
  <h1>${value}</h1>
</template>

////////////////////////////

import {bindable} from 'aurelia-framework';

export class MyCustomElement {
  @bindable value;

  valueChanged(newValue, oldValue) {      }
}

Custom Component:

<template>
  <h1>${message}</h1>
</template>

////////////////////////////

export class MyCustomComponent {    
  message: string;
  
  constructor() {
    this.message = 'Hello world';
  }
}

I don’t understand the situations or contexts in which you would use one over the other (or, assuming they’re not comparable, in what circumstances you should use each).

I do completely understand the difference between them if custom elements had only a view component (i.e. html file) and were therefore just a way to essentially modularize repeating snippets of html that you’d want to populate with different data (like cards in a grid or rows in a table) that don’t require any logic. But if custom elements are also able to have a view model as well, and therefore their own logic, then wouldn’t that essentially just make them custom components at that point?

(Note that I asked the same question on Stack Overflow a while back here, but the one answer didn’t explain it well enough for me to understand.)

I think the component is for the page that you link in the router config (AKA moduleId) otherwise it just a custom element

They are exactly the same thing. You can switch them out and see no difference.

Difference is in instantiation and lifecycle… when a view-model/view pair is routed to… the activate() is called… but constructor is called once and components are singletons by default. Which means that they preserve state that you don’t set up in activate

Custom elements are instantiated for each use. And activate is not called

5 Likes

We need this in the docs somewhere. I might have it missed it but I was a bit confused as well when reading the docs.

1 Like

Thanks! I think that’s the best explanation I’ve heard so far.

And I totally agree with @lovetostrike in that this should be documented somewhere. There’s nothing more confusing when trying to learn a system than seeing two almost identical things and not understanding how they relate to one another (ie what the differences and similarities are).