DEV Community

Cover image for Signalize.js - Introduction to Modular Javascript Framework
Vladimír Macháček
Vladimír Macháček

Posted on

Signalize.js - Introduction to Modular Javascript Framework

Signalize 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 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.
<!-- 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>
Enter fullscreen mode Exit fullscreen mode

The Ecosystem

The Signalize 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:

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 and Binding modules.
  • I have a carousel with dynamic products: Use the Ajax module and manually redraw Snippets.
  • I need reusable components: Use Web Components
  • I need more complex forms: Import Directives
  • I want to turn my website into an SPA: Add the SPA module.

A simple example with Signals & Reactivity.

You can edit this example in the playground

<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>
Enter fullscreen mode Exit fullscreen mode

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.

Bellow is a simplified example:

1 - Install Signalize:

npm i signalizejs
Enter fullscreen mode Exit fullscreen mode

2 - Create src/assets/layout.js

import Signalize from 'signalizejs';

export const signalize = new Signalize();
Enter fullscreen mode Exit fullscreen mode

3 - Create src/layouts/main.astro

---
// 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>
Enter fullscreen mode Exit fullscreen mode

4 - Create src/pages/index.astro

---
// 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>
Enter fullscreen mode Exit fullscreen mode

Let me know what you think!

If you like the idea, let me know by starring the Signalize repo.

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.


Top comments (2)

Collapse
 
intermundos profile image
intermundos

Looks very interesting, particularly for using with Astro.

Do you have more examples of using signalize with Astro?

Thanks!

Collapse
 
machy8 profile image
Vladimír Macháček • Edited

Hi. Thanks!

In which examples you would be interested in?

I use it on my websites but they run in Symfony (prace.dev) and Go (travellingvisio.com) so not probably what you have in mind.