WebComponents as the standard should be. @github/catalyst
Tags: github, catalyst, webcomponents, customelements
Published: 2020-12-07 16:54:20

> :warning: **Don't confuse @github/catalyst with the perl framework Catalyst (also hosted in github).**


## Good approach, No magic, Production ready.

First of all, don't look for Virtual DOM or Two-way binding in here. But some existing libraries are probably very good to doing this kind of things.

Many developers feel that [Web Components](https://developer.mozilla.org/en-US/docs/Web/Web_Components) still have to improve or the standard should contain those features. IMHO it would be very cool have what React, Vue or Angular already do but with just native custom elements, but the scene is not jet that.

Anyway every day more companies are choosing web components to build/improve their modern web pages. And Github is one of these companies

To make the gap smaller [github](https://github.com/github/catalyst) have just shipped a nice set of helpers using Typescript (mainly the decorators). It's only on the version 1.0.2, but everything shipped is already working in github.com.


## Less Boilerplate

Catalyst makes use of decorators to save some repetitive code that every custom element needs. The main one is `@controller` to decorate the whole class.

```js
@controller
class TodoAppElement extends HTMLElement {

    connectedCallback() {
        //...
    }
}
```

Automatically the class is register by calling `customElement.register` with the proper name, in the case above it would be `todo-app` removing the sufix "Element" from the name.

To make us the live easier `@controller` also injects a call to `bind(this)` in the `connectedCallback`. This makes the actions work in the current scope.



## Actions and Targets

The main interaction between the dom and the web component class is made by delegating actions (callbacks), that will be public methods in the current class.

In the `data-action` we have to specify the dom event, webcomponent name and callback name and the binding will be done.


```js
<div>
    <button data-action="click:todo-item#handleOnRemoved"></button>
</div>
```

A class field decorated with `@target` will receive the respective dom element. So the field `@target elem;` will receive a element marked as `data-target="component-name.elem"`.

The HTMLElemenet can be a target and also the source of actions.

```js
<input
    class="new-todo"
    data-target="todo-input.text"
    data-action="keyup:todo-input#handleInputChange"
    type="text"
    placeholder="What needs to be done?"
    />
```

## Custom Events

Let's don't forget that we are working with just HTMLElments, so in the end we can receive a DOM Event as well as a [Custom Event](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent) from a nested web coponent. Actions can handle any kind of event and fire any callback defined.

```js
<todo-item
    data-action="
        removed:todo-list#handleOnRemoved
        checked:todo-list#handleOnChecked
    "
    ></todo-item>
```

Just by adding extra lines in the `data-action` attribute the callbacks will be binded.

## Conclusion

Thanks for reading up to here, this was just a quick summary of what I learned by messing around with [@github/catalyst](https://www.npmjs.com/package/@github/catalyst).

You can check the full code of the [ToDo List app here](https://github.com/Scipion/catalyst-todo).

As I said at the begining, I don't think catalyst is a replacement for modern frameworks but It can be an alternative in the future for other similar tools (today much more matures) like [LitElement](https://lit-element.polymer-project.org/) or [Svelte](https://svelte.dev/).

It's still a very young package but let's keep an eye on what Github can ship in the future.