Skip to content

πŸ› οΈ A Dart package enabling the use of Node.js-based Web Workers in Flutter web applications, providing seamless integration of Dart and JavaScript workers for improved performance.

License

Notifications You must be signed in to change notification settings

printHelloworldd/flutter-node-worker

Repository files navigation

πŸ“– Description

flutter_node_worker is a tool and library for Flutter Web that enables multithreading via Web Workers written in Node.js.

Unlike Flutter on other platforms, Isolate is not supported on Web, making it impossible to perform heavy computations outside the main thread. To avoid blocking the UI during long operations, it is recommended to use Web Workers, and this is what this package provides.

This is especially useful for cryptographic operations, parsing, computing, and any CPU-intensive operations.


πŸ“¦ Features

  • ✍️ Node.js worker logic using any npm packages

  • βš’οΈ Automatic project template generation (init)

  • ⚑ Build via Vite

  • 🧠 Integration of Web Workers into Flutter with a type-safe API

  • 🎯 Support for multi-command logic and data transfer in both directions


🧠 Where to use

  • Cryptographic methods
  • Large calculations (parsing, math, crypto)
  • JSON β†’ Protobuf / MsgPack conversion
  • Working with npm libraries directly from Flutter
  • Parsers, transformers and generators

Table of contents


πŸ“₯ Get started

Add dependency

dependencies:
  flutter_node_worker: any

or using command

flutter pub add flutter_node_worker

Install dependencies:

flutter pub get

πŸš€ Quick start and usage example

1. Initialize a new worker

dart run flutter_node_worker init --dir my_worker --name encryptor

Creates a template in the my_worker/ folder with the worker name encryptor.

Additionally, this will generate a Makefile and a Bash script fnw in your project root, allowing you to run commands with shorter syntax.

πŸ“Œ See CLI-commands below for details on using dart run, ./fnw, or make.

2. πŸ”’ Write the worker logic

Inside src/encryptor.js (for example, a cryptographic method for encrypting data):

import forge from 'node-forge';

self.onmessage = function (e) {
  const { command, data } = e.data;

  if (command === "encrypt") {
    const result = encrypt(data.message, data.password);
    self.postMessage(JSON.stringify({ status: "success", command, result: { message: result } }));
  }
}

function encrypt(message, password) {
	// Encryption logic
}

If the worker will use a third-party library, it can be imported as an ES module, but don't forget to install it using:

dart run flutter_node_worker install <package-name> --dir my_worker

or:

cd my_worker
npm install <package-name>

3. Build a module worker

dart run flutter_node_worker build --dir my_worker --out-dir ../web/workers

or:

cd my_worker
npm run build

Creates a built module worker in web/workers/ with the worker name + module.js (in this example encryptor_module.js). It can now be used in Dart code. If you do not specify --out-dir, the worker will be built in my_worker/dist/. The --out-dir should be specified relative to the worker's directory, not the project root.
For example, if your worker is in my_worker, use --out-dir=../web/workers.


4. Use a worker in Flutter Web

final worker = FlutterNodeWorker(path: "my_worker/dist/encryptor_module.js");

final result = await worker.compute(
  command: "encrypt",
  data: {"message": "Hello", "password": "secret"},
);

🧩 Structure

my_worker/
β”œβ”€β”€ package.json
β”œβ”€β”€ vite.config.js
β”œβ”€β”€ src/
β”‚   └── encryptor.js       // Your worker logic
β”œβ”€β”€ dist/
β”‚   └── encryptor_module.js  // Compiled worker module

πŸ“š API

FlutterNodeWorker

FlutterNodeWorker({required String path})

Methods

  • compute({command, data, computeOnce})
    Sends a command and data to the worker and returns the result.

    • If computeOnce = true (default is false), the worker will automatically exit after the command is executed - useful for rare operations like generating cryptographic keys on registration.

    • If computeOnce = false, the worker remains active, which is suitable for frequent tasks such as encrypting chat messages.

  • terminate()
    Manually terminates the worker, freeing up resources.


CLI-commands

Each command can be run in one of three ways:

Method Example
dart run dart run flutter_node_worker init --dir my_worker --name encryptor
Bash script ./fnw init --dir my_worker --name encryptor
Makefile make init dir=my_worker name=encryptor

init β€” Generate worker template

dart run flutter_node_worker init --dir my_worker --name encryptor
./fnw init --dir my_worker --name encryptor
make init dir=my_worker name=encryptor

build β€” Build worker module via Vite

dart run flutter_node_worker build --dir my_worker --out-dir ../web/workers
./fnw build --dir my_worker --out-dir ../web/workers
make build-worker dir=my_worker out-dir=../web/workers

The --out-dir should be specified relative to the worker's directory, not the project root.
For example, if your worker is in my_worker, use --out-dir=../web/workers.


add β€” Add new worker script

dart run flutter_node_worker add --dir my_worker --name decryptor
./fnw add --dir my_worker --name decryptor
make add dir=my_worker name=decryptor

install β€” Install npm package to worker

dart run flutter_node_worker install uuid --dir my_worker
./fnw install uuid --dir my_worker
make install dir=my_worker pkgs=uuid

uninstall β€” Remove npm package

dart run flutter_node_worker uninstall uuid --dir my_worker
./fnw uninstall uuid --dir my_worker
make uninstall dir=my_worker pkgs=uuid

CLI Arguments

Argument Abbreviation Description
--dir -d The directory in which the command is executed (init, build, add, etc.)
--name -n Worker name when initializing or adding a new one
--out-dir -o Directory where the compiled module will be placed

πŸ› οΈ Dependencies


πŸ–ΌοΈ Demo

The demo application allows you to encrypt and decrypt a message using a password. For clarity, an animation has been added demonstrating that the main thread is not blocked - the UI remains responsive even when performing heavy operations.

By opening DevTools β†’ Sources β†’ Threads, you can see the active threads, including the Web Worker (cipher_module.js), where the calculation takes place.

CHECK WEB DEMO


πŸš€ What's Next

  • Cover the project with unit and integration tests

  • Switch from dart:js to dart:js_interop for safer and more typed work with JavaScript

  • Improve Web Worker error handling

  • Add logging and notifications when the worker crashes

  • Support for custom templates and configurations


🀝 Support

Open an issue or pull request. Any help is appreciated!


🀝 Contributors

Thanks to all these amazing people:

Contributors

About

πŸ› οΈ A Dart package enabling the use of Node.js-based Web Workers in Flutter web applications, providing seamless integration of Dart and JavaScript workers for improved performance.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published