Signalize.js - Introduction to Modular Javascript Framework
Tags: javascript, webdev, beginners, programming
Published: 2024-06-24 05:00:00

[Signalize](https://signalizejs.com) is a client-side JavaScript framework designed for swift web development with minimal JavaScript.

**Signalize:**
- Leverages modern **ES modules** and **import maps**.
- Imports only a small **2 KB core**, allowing **you to decide what to import and when**.

The goal is to provide functionality similar to modern frameworks like Vue, Svelte, Solid, and Qwik, but with minimal JavaScript, the smallest possible learning curve, a simple codebase, no dependencies, and no need for a JavaScript backend.

## Signalize in a Nutshell

Let's start with a simple example of how Signalize works:
- [Signalize](https://signalizejs.com) is split into several JavaScript modules.
- Each module provides different functionality.
- To use Signalize, you need to define an import map first.
- Then, you import the core and create a new Signalize instance.
- This new instance will provide you with the `resolve` function for loading modules.
- Every time you need some functionality, you import it using the resolve function.
- Signalize internally reuses modules and automatically loads dependencies in the correct order to keep the framework small.

```html
<!-- 1. Configure the importmap -->
<script type="importmap">
{
  "imports": {
    "signalizejs": "https://cdn.jsdelivr.net/npm/signalizejs@latest/+esm",
    "signalizejs/mutation-observer": "https://cdn.jsdelivr.net/npm/signalizejs@latest/mutation-observer/+esm",
    "signalizejs/dom/ready": "https://cdn.jsdelivr.net/npm/signalizejs@latest/dom/ready/+esm",
    "signalizejs/event": "https://cdn.jsdelivr.net/npm/signalizejs@latest/event/+esm"
  }
}
</script>
<script type="module">
    // 2. Import the Signalize core
    import Signalize from 'signalizejs';

    // 3. Create a new Signalize instance
    const { resolve } = new Signalize();

    // 4.1 Resolve the Event module because we need the "on" function
    // 4.2 The Event module will automatically import the Mutation Observer module
    const { on } = await resolve('event', 'dom/ready');

    // 5. Use the on function
    on('dom:ready', () => alert('Hello World!'));
</script>
```

## The Ecosystem
The [Signalize](https://signalizejs.com) ecosystem currently contains 25 modules focused on solving web development problems such as reactivity, web components, Ajax, SPA, error logging, and various utilities. The number of modules will definitely grow.

Here is a list of a few of them:
- **Signals & Reactivity**: [signal](https://signalizejs.com/docs/modules/signal), [bind](https://signalizejs.com/docs/modules/bind)
- [Directives](https://signalizejs.com/docs/modules/directives)
- [Web Components](https://signalizejs.com/docs/modules/component)
- [SPA](https://signalizejs.com/docs/modules/spa)
- [Dialogs](https://signalizejs.com/docs/modules/dialog)
- [Logger](https://signalizejs.com/docs/modules/logger)
- **Web Perf**: [Task](https://signalizejs.com/docs/modules/task)
- **Utils**: [Ajax](https://signalizejs.com/docs/modules/ajax)

## The Mindset
The basic idea is to import only what you need. Not everything needs to be a complex app with tons of features:
- **I need some simple reactivity**: Use the [Signals](https://signalizejs.com/docs/modules/signal) and [Binding](https://signalizejs.com/docs/modules/bind) modules.
- **I have a carousel with dynamic products**: Use the [Ajax](https://signalizejs.com/docs/modules/ajax) module and manually redraw [Snippets](https://signalizejs.com/docs/modules/snippets).
- **I need reusable components**: Use [Web Components](https://signalizejs.com/docs/modules/component)
- **I need more complex forms**: Import [Directives](https://signalizejs.com/docs/modules/directives)
- **I want to turn my website into an SPA**: Add the [SPA](https://signalizejs.com/docs/modules/spa) module.

### A simple example with Signals & Reactivity. 
[You can edit this example in the playground](https://signalizejs.com/playground?code=%3Cbutton%3E%0A%20%20Count%3A%20%3Cspan%3E%3C%2Fspan%3E%0A%3C%2Fbutton%3E%0A%0A%3Cscript%20type%3D%22importmap%22%3E%0A%7B%0A%20%20%22imports%22%3A%20%7B%0A%20%20%20%20%22signalizejs%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2F%2Besm%22%2C%0A%20%20%20%20%22signalizejs%2Fbind%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2Fbind%2F%2Besm%22%2C%0A%20%20%20%20%22signalizejs%2Fevent%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2Fevent%2F%2Besm%22%2C%0A%20%20%20%20%22signalizejs%2Fmutation-observer%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2Fmutation-observer%2F%2Besm%22%2C%0A%20%20%20%20%22signalizejs%2Fscope%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2Fscope%2F%2Besm%22%2C%0A%20%20%20%20%22signalizejs%2Fsignal%22%3A%20%22https%3A%2F%2Fcdn.jsdelivr.net%2Fnpm%2Fsignalizejs%2Fsignal%2F%2Besm%22%0A%20%20%7D%0A%7D%0A%3C%2Fscript%3E%0A%0A%3Cscript%20type%3D%22module%22%20defer%3E%0A%09import%20Signalize%20from%20'signalizejs'%3B%0A%0A%09const%20%7B%20resolve%20%7D%20%3D%20new%20Signalize()%3B%0A%0A%09%2F%2F%20You%20code%20goes%20here%0A%09const%20%7B%20signal%2C%20bind%20%7D%20%3D%20await%20resolve('signal'%2C%20'bind')%3B%0A%0A%20%20%20%20const%20number%20%3D%20signal(0)%3B%0A%20%20%20%20%0A%20%20%20%20document.querySelector('button').addEventListener('click'%2C%20()%20%3D%3E%20number(number()%20%2B%201))%3B%0A%20%20%20%20bind(document.querySelector('span')%2C%20%7B%20text%3A%20number%20%7D)%3B%0A%3C%2Fscript%3E)
```html
<button>
  Count: <span></span>
</button>

<script type="importmap">
{
  "imports": {
    "signalizejs": "https://cdn.jsdelivr.net/npm/signalizejs/+esm",
    "signalizejs/bind": "https://cdn.jsdelivr.net/npm/signalizejs/bind/+esm",
    "signalizejs/event": "https://cdn.jsdelivr.net/npm/signalizejs/event/+esm",
    "signalizejs/mutation-observer": "https://cdn.jsdelivr.net/npm/signalizejs/mutation-observer/+esm",
    "signalizejs/scope": "https://cdn.jsdelivr.net/npm/signalizejs/scope/+esm",
    "signalizejs/signal": "https://cdn.jsdelivr.net/npm/signalizejs/signal/+esm"
  }
}
</script>

<script type="module" defer>
	import Signalize from 'signalizejs';

	const { resolve } = new Signalize();

	// You code goes here
	const { signal, bind } = await resolve('signal', 'bind');

    const number = signal(0);
    
    document.querySelector('button').addEventListener(
      'click',
      () => number(number() + 1)
    );
    bind(document.querySelector('span'), { text: number });
</script>
```

## A simple example with Astro.build
Do you like Astro.build? It converts JavaScript into ES modules, so Signalize works very well with Astro. I wrote a guide on [how to use Signalize in Astro](https://signalizejs.com/docs/installation/astro).

Bellow is a simplified example:

**1 - Install Signalize:**
```
npm i signalizejs
```

**2 - Create `src/assets/layout.js`**
```js
import Signalize from 'signalizejs';

export const signalize = new Signalize();
```

**3 - Create `src/layouts/main.astro`**
```html
---
// 1. Get signalizejs url
import signalize from 'signalizejs?url';

// 2. Get event module url. This applies for all modules you will need.
import eventModuleUrl from 'signalizejs/event?url';

// 3. Define importmap
const importMap = JSON.stringify({
	imports: {
		// 4. Configure necessary modules
		'signalizejs/event': eventModuleUrl,
		// Other modules you need
	}
});
---

<html>
	<head>
		<!-- 5. Embed the import map -->
		<script type="importmap" :html={importMap}></script>
		<!-- 6. Create a global Signalize instance -->
		<script>
			import "../assets/layout.js";
		</script>
	</head>
	<body>
		<slot />
	</body>
</html>
```

**4 - Create `src/pages/index.astro`**
```html
---
// src/pages/index.astro
import MainLayout from '../layouts/main.astro';
---
<MainLayout>
	<script>
		import { signalize } from '../assets/layout.js';

		const { on } = await signalize.resolve('event');
	</script>
</MainLayout>
```

## Let me know what you think!
If you like the idea, let me know by [starring the Signalize repo](https://github.com/signalizejs/signalize).

I welcome any feedback because Signalize is a new library and there is definitely room for improvement. 🙂

## Stay in Touch!
I plan to write about the reactivity inspired by Solid and Angular Signals, the bindings and directives inspired by Svelte, and the ES module loader for dependency injection inspired by Qwik's loader.

If you want to get inspired for your next project or learn something new, it's a great place to start.

---
- [@signalizejs](https://twitter.com/signalizejs)
- [Signalizejs.com](https://signalizejs.com)
- [Signalize Discord](https://discord.gg/V82TvAVRKY)
- [Signalize Repo](https://github.com/signalizejs/signalize)
- [@8machy](https://twitter.com/8machy)