PlumeJS - No fuss web-components framework
Tags: javascript, html, programming, opensource
Published: 2024-04-16 10:49:23

Hello Everyone.

Have you considered writing HTML in this manner?

```HTML
`<button onclick=${() => { alert('hello world'); }}>click me</button>`
```

unlike any other framework out there (upto my broad knowledge. i may miss one), binding events don't require any special syntax. It's just plain string interpolation. Wondering how? I would like to introduce you to a new kid in Framework Town: **[PlumeJS](https://github.com/KiranMantha/plumejs)**.

PlumeJS is a framework that relies on web components. As you are all aware, the browser defines and regulates the life cycle of a web component. PlumeJS is a lightweight framework out there due to this.

This framework provides the ability to create reusable web components, routing and dependency injection for sharing data across components all in a ~27kb package (~8kb when brotli compressed) which includes routing and forms support.

PlumeJS has very few to zero external dependencies. That means, you can make use of the latest `importmaps` to include PlumeJS and use just like that. Sounds exiting right?? 

So how a typical component declaration looks like in PlumeJS?

```javascript
import { Component } from '@plumejs/core';

@Component({
  selector: 'app-root'
})
class AppComponent {
  render() {
     return `<h1>hello world</h1>`;
  }
}
```

Looks familiar? Yes, it adopts angular-like component declarations and react-like HTML in JS coding style.

You can re-write the above code in another way too..

```javascript
import { Component } from '@plumejs/core';

class AppComponent {
  render() {
     return `<h1>hello world</h1>`;
  }
}
Component({
  selector: 'app-root'
})(AppComponent)
```

This helps to reduce the bundle size by not including decorator snippets at the beginning of the files benefiting the final build size. 

Just like angular, any change in class variables trigger change detection. PlumeJS uses queueMicroTask to re-render the component upon any changes. 

For example, this is how a simple counter component looks like:
```typescript
import { Component, html } from '@plumejs/core';

@Component({
  selector: 'app-counter'
})
class Counter {
  count = 0;

  render() {
    return html`<h1>Hello world</h1>
    <button onclick=${() => {
      this.count--;
    }}>
      -
    </button>
      <span>${this.count}</span>
    <button onclick=${() => {
      this.count++;
    }}>
      +
    </button>`;
  }
}
```

Components can talk to each other either by `parent-child` relation or by `services` or by `routing`.

We all know that web-components excel at scoping html, javascript and css. PlumeJS extends one helping hand to this by incorporating [CSSStyleSheet Constructor](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet) and [adoptedStyleSheets](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/adoptedStyleSheets) for true css encapsulation and sharing global styles. If incase `CSSStyleSheet` is not supported by your browser, PlumeJS automatically resorts to css emulation.

The entire framework is available as a single file from cdn in either [IIFE](https://cdn.jsdelivr.net/gh/kiranmantha/plumejs-esnext/build/plume.iife.js) / [ES Module](https://cdn.jsdelivr.net/gh/kiranmantha/plumejs-esnext/build/plume.es.js) / [UMD](https://cdn.jsdelivr.net/gh/kiranmantha/plumejs-esnext/build/plume.umd.js) formats if you want to use it via `importmaps` **or** it is also availble on npm as `scoped-packages`. 

Yes for better maintainability, PlumeJS has 4 main scoped packages and 1 addon scoped package

## Main packages:

1. [@plumejs/core](npmjs.com/package/@plumejs/core) : This is the main and core package that helps us to create components / services.
2. [@plumejs/router](npmjs.com/package/@plumejs/router) : As the name implies, this scoped package helps us to enable routing.
3. [@plumejs/forms](npmjs.com/package/@plumejs/forms) : This scoped package helps us to create robust forms. 
4. [@plumejs/testing](npmjs.com/package/@plumejs/testing) : A scoped package for wrting unit tests based on `vitest` and `JSDom`.

## Addon package:

1. [@plumejs/ui](npmjs.com/package/@plumejs/ui) : This scoped package contains a collection of UI components like dialogs, multi-select, notifications, toggles. 

PlumeJS has a user-friendly [Yeoman generator](https://www.npmjs.com/package/generator-plumejs) to ease project setup based on either `vite` or `webpack`. 

For more info on usage docs, please visit [PlumeJS Wiki](https://github.com/KiranMantha/plumejs/wiki). 

I hope you like my attempt to make web-components great.

Drop a star or contribute a pull request if you like :blush:.

Hoping to see your feedback,
See you again,
Kiran :wave: :wave: