Efficient State Management in JavaScript Apps with Statemanjs
Tags: javascript, webdev, tutorial, opensource
Published: 2023-01-12 01:04:48

When developing JavaScript applications, it is important to consider its limitations such as the lack of thread support, single-threaded execution model, limited support for large numbers and high-precision arithmetic etc. These limitations can narrow the scope of the language, but it remains the premier language in modern web development. As web applications become more complex, developers may encounter performance issues. There are various ways to optimize a web application, but one aspect to consider is state management.

State management is a critical aspect of building modern JavaScript applications. It allows developers to manage and manipulate the data that drives their applications, and helps ensure that the application is reliable, scalable, and maintainable. There are many state management libraries available, each with its own set of features, trade-offs, and limitations. In this article, we will focus on Statemanjs, a framework-agnostic state management library for JavaScript and Node.js applications. We will explore the key features and benefits of Statemanjs, and I explain why it is the best choice for state management in JavaScript applications.
But first, let's see which approaches of state management we have.

## Approaches to state management:

There are several approaches to state management in JavaScript - immutable, reactive, and mutable. Each with its own set of benefits and limitations.

**Immutable approach:** The immutable approach involves creating new copies of the state whenever it is updated, rather than modifying the state directly. This can provide a higher level of security and reliability, as it prevents accidental or unauthorized changes to the state. However, the immutable approach can be inefficient in JavaScript due to the single-threaded execution model and event loop.

**Reactive approach:** The reactive approach involves defining dependencies between state updates and automatically re-executing updates when the dependencies change. The reactive approach may be slower in other cases, and it can be more complex to learn and use than other approaches.

**Mutable approach:** The mutable approach involves updating the state directly, rather than creating new state copies or tracking dependencies. This can be faster and more efficient than the immutable or reactive approaches, and it can be simpler to understand and implement. However, the mutable approach may provide a lower level of security and reliability, as it allows developers to modify the state directly.

## Quick Overview:

Statemanjs is a framework-agnostic state management library for JavaScript and Node.js applications. It is written in TypeScript, which provides excellent support out of the box, and it has a tiny size, less than 80 KB (unpacked).

Statemanjs uses a mutable approach to state management with read-only state links, and strict API for interacting with state. Let's dive deeper.

## Performance:

One of the main benefits of Statemanjs is its superior performance compared to other state management libraries. Statemanjs uses a mutable approach to state management, which updates the state directly and avoids the overhead of creating new state copies or tracking dependencies. This can make Statemanjs faster and more efficient than libraries that use immutable or reactive approaches, such as Redux or MobX.

To benchmark the performance of these libraries, we used a test case that involves adding n elements to an array a certain number of times - x. The element is an object `{foo: "bar", baz: "qux"}`. Between iterations, the storage (i.e., the array) is reset to an empty array.
For example: if _n = 5_ and _x = 2_, that means to add 5 elements 2 times (iteration).
The average value for iterations is calculated and written as the result.

In this benchmark, Statemanjs consistently outperforms both Redux and MobX. For example, with _n = 100000_ and _x = 10_, the results are:

<table>
<thead>
  <tr>
    <th style="background-color: dimgray;">Lib</th>
    <th style="background-color: dimgray;">Res (ms)</th>
  </tr>
</thead>
<tbody>
    <tr>
        <td>Redux</td>
        <td>2354867.223542001</td>
    </tr>
    <tr>
        <td>MobX</td>
        <td>4473.258667119965</td>
    </tr>
    <tr>
        <td>Statemanjs</td>
        <td>279.83934087000785</td>
    </tr>
</tbody>
</table>

As you can see, Statemanjs is more than **8,000** times faster than Redux and nearly **16** times faster than MobX in this benchmark. With larger numbers of elements or more complex update logic, the performance difference between Statemanjs and other libraries becomes even more pronounced.

For example, with n = 50000000 (50 million elements) and _x = 1_ (1 iteration), both Redux and MobX fail to complete the benchmark after more than 6 hours of execution, while Statemanjs completes the benchmark in just 14499.883542001247ms (14.5 seconds).

## Simplicity:

In addition to its superior performance, Statemanjs is also simpler to understand and use than other state management libraries. It has a clear and strict API, with just seven methods for interacting with the state: `set`, `get`, `subscribe`, `unsubscribeAll`, `getActiveSubscribersCount`, `unwrap` and `update`. These methods allow developers to set and retrieve the state, subscribe to state changes, and update the state in a controlled and reliable manner. Statemanjs also offers read-only state links, which provide restricted access to the state and prevent accidental or unauthorized changes.

This simple and straightforward API can make it easier for developers to learn and use Statemanjs, especially if they are new to state management or have limited experience with other libraries. It also allows developers to focus on the core logic of their applications, rather than spending time learning complex APIs or writing boilerplate code.

## Scalability:

Statemanjs is highly scalable and suitable for both small and large projects. It can handle a wide range of state types, from primitives to complex and multidimensional objects, and it is easy to use with any front-end framework, including React, Vue, and Svelte. Statemanjs also has a small package size, with no dependencies and a footprint of less than 80 KB (unpacked), which makes it easy to include in any project without bloating the application.

In addition to its scalability, Statemanjs also has excellent support for TypeScript out of the box. This can make it easier for developers to write and maintain type-safe code, and can help reduce the risk of errors and bugs in their applications.

## Reliability:

Statemanjs also offers a high level of security and reliability compared to other state management libraries. Its strict API and read-only state links prevent accidental or unauthorized changes to the state, and its mutable approach ensures that state updates are fast and efficient. These features can help developers build more reliable and maintainable applications, and can reduce the risk of errors and bugs in their code.

By default, the state references are read-only, and you can only change the state using API methods.

## Simple demo

This is the demo with TypeScript:

```ts
import { createState } from "@persevie/statemanjs";

type TransferElement = {
    speed: number;
    info: string;
    error?: string;
};

// Create a new state with initial value { speed: 0, info: "" }
const transferState: = createState<TransferElement>({ speed: 0, info: "" });

// Subscribe to state changes and log the updated state
const unsubscribe = transferState.subscribe((state) => {
  console.log("State updated:", state);
});

// Update the state to { speed: 50, info: "Transfer in progress" }
transferState.update((state) => {
  state.speed = 50;
  state.info = "Transfer in progress";
});

// Get the current state
const currentState = transferState.get();
console.log("Current state:", currentState);

// Unsubscribe from state updates
unsubscribe();

// Subscribe to state changes, but only log the updated state if the error
transferState.subscribe(
  (state) => {
    console.log("An error occurred:", state.error);
  },
  {
    notifyCondition: (state) => {
      state.error !== undefined;
    },
  },
);

// Set (create new object and replace old) the state to { speed: 0, info: "Ooops...", error: "Internet connection" }
transferState.set({
  speed: 0;
  info: "Ooops...",
  error: Internet connection,
});

console.log("Active subscribers count:", transferState.getActiveSubscribersCount());

// Remove all subscribers
transferState.unsubscribeAll();

console.log("Active subscribers count after unsubscribe:", transferState.getActiveSubscribersCount());

// Output:
// "State updated: { speed: 50, info: "Transfer in progress" }"
// "Current state: { speed: 50, info: "Transfer in progress" }"
// "An error occurred: "Internet connection""
// "Active subscribers count: 1"
// "Active subscribers count after unsubscribe: 0"
```

## Conclusion:

In conclusion, Statemanjs is an excellent choice for state management in JavaScript applications. Its superior performance, simplicity, scalability, and reliability make it a standout among other state management libraries, and it is well-suited for a wide range of projects and frameworks. If you are looking for a powerful and efficient state management library for your JavaScript application, **Statemanjs is a top choice**.

[Statemanjs GitHub link](https://github.com/persevie/statemanjs)

[Statemanjs-react GitHub link](https://github.com/persevie/statemanjs-react)

[Statemanjs-vue GitHub link](https://github.com/persevie/statemanjs-vue)

[Statemanjs-solid GitHub link](https://github.com/persevie/statemanjs-solid)