{"id":29466252,"url":"https://github.com/printhelloworldd/flutter-node-worker","last_synced_at":"2026-04-13T13:02:53.836Z","repository":{"id":302159391,"uuid":"1009827059","full_name":"printHelloworldd/flutter-node-worker","owner":"printHelloworldd","description":"🛠️ 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.","archived":false,"fork":false,"pushed_at":"2025-08-03T08:05:28.000Z","size":24698,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-08-03T10:05:58.014Z","etag":null,"topics":["dart","dart-library","dart-package","dartjs","dartlang","flutter","flutter-demo","flutter-examples","flutter-l","flutter-package","flutter-web","javascript","js-interop","module-workers","mul","nodejs","package","vite","web","webworker"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/printHelloworldd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-27T19:29:45.000Z","updated_at":"2025-08-03T08:05:31.000Z","dependencies_parsed_at":"2025-08-03T10:10:57.022Z","dependency_job_id":null,"html_url":"https://github.com/printHelloworldd/flutter-node-worker","commit_stats":null,"previous_names":["printhelloworldd/flutter-node-worker"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/printHelloworldd/flutter-node-worker","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/printHelloworldd%2Fflutter-node-worker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/printHelloworldd%2Fflutter-node-worker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/printHelloworldd%2Fflutter-node-worker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/printHelloworldd%2Fflutter-node-worker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/printHelloworldd","download_url":"https://codeload.github.com/printHelloworldd/flutter-node-worker/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/printHelloworldd%2Fflutter-node-worker/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281361402,"owners_count":26487881,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-27T02:00:05.855Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dart-library","dart-package","dartjs","dartlang","flutter","flutter-demo","flutter-examples","flutter-l","flutter-package","flutter-web","javascript","js-interop","module-workers","mul","nodejs","package","vite","web","webworker"],"created_at":"2025-07-14T09:01:11.297Z","updated_at":"2025-10-27T23:35:10.950Z","avatar_url":"https://github.com/printHelloworldd.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## 📖 Description\n\n`flutter_node_worker` is a tool and library for Flutter Web that enables **[multithreading](https://en.wikipedia.org/wiki/Multithreading_(computer_architecture)) via [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers)** written in [Node.js](https://nodejs.org/).\n\nUnlike Flutter on other platforms, **[Isolate](https://docs.flutter.dev/perf/isolates) 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.\n\nThis is especially useful for cryptographic operations, parsing, computing, and any CPU-intensive operations.\n\n---\n\n## 📦 Features\n\n- ✍️ `Node.js` worker logic using any `npm` packages\n\t\n- ⚒️ Automatic project template generation (`init`)\n\t\n- ⚡ Build via `Vite`\n\t\n- 🧠 Integration of Web Workers into Flutter with a type-safe API\n\t\n- 🎯 Support for multi-command logic and data transfer in both directions\n\n---\n\n## 🧠 Where to use\n\n- Cryptographic methods\n- Large calculations (parsing, math, crypto)\n- JSON → Protobuf / MsgPack conversion\n- Working with npm libraries directly from Flutter\n- Parsers, transformers and generators\n\n---\n\n## Table of contents\n\n- [📖 Description](#-description)\n- [📦 Features](#-features)\n- [🧠 Where to use](#-where-to-use)\n- [Table of contents](#table-of-contents)\n- [📥 Get started](#-get-started)\n  - [Add dependency](#add-dependency)\n  - [🚀 Quick start and usage example](#-quick-start-and-usage-example)\n    - [1. Initialize a new worker](#1-initialize-a-new-worker)\n    - [2. 🔒 Write the worker logic](#2--write-the-worker-logic)\n      - [Worker Response Format](#worker-response-format)\n    - [3. Build a module worker](#3-build-a-module-worker)\n    - [4. Use a worker in Flutter Web](#4-use-a-worker-in-flutter-web)\n- [🧩 Structure](#-structure)\n- [📚 API](#-api)\n  - [`FlutterNodeWorker`](#flutternodeworker)\n    - [Methods](#methods)\n- [CLI-commands](#cli-commands)\n  - [`init` — Generate worker template](#init--generate-worker-template)\n  - [`build` — Build worker module via Vite](#build--build-worker-module-via-vite)\n  - [`add` — Add new worker script](#add--add-new-worker-script)\n  - [`install` — Install npm package to worker](#install--install-npm-package-to-worker)\n  - [`uninstall` — Remove npm package](#uninstall--remove-npm-package)\n  - [CLI Arguments](#cli-arguments)\n- [🛠️ Dependencies](#️-dependencies)\n- [🖼️ Demo](#️-demo)\n- [🤝 Support](#-support)\n- [🤝 Contributors](#-contributors)\n\n---\n\n## 📥 Get started\n\n### Add dependency\n\n```yaml\ndependencies:\n  flutter_node_worker: any\n```\n\nor using command\n\n```bash\nflutter pub add flutter_node_worker\n```\n\nInstall dependencies:\n\n```bash\nflutter pub get\n```\n\n### 🚀 Quick start and usage example\n\n#### 1. Initialize a new worker\n```bash\ndart run flutter_node_worker init --dir my_worker --name encryptor\n```\n\nCreates a template in the `my_worker/` folder with the worker name `encryptor`.\n\nAdditionally, this will generate a `Makefile` and a Bash script `fnw` in your project root, allowing you to run commands with shorter syntax.\n\n📌 See [CLI-commands](#CLI-commands) below for details on using `dart run`, `./fnw`, or `make`.\n\n#### 2. 🔒 Write the worker logic\n\nInside `src/encryptor.js` (for example, a cryptographic method for encrypting data):\n\n```js\nimport forge from 'node-forge';\n\nself.onmessage = function (e) {\n  const { command, data } = e.data;\n\n  if (command === \"encrypt\") {\n    const result = encrypt(data.message, data.password);\n    self.postMessage(JSON.stringify({ status: \"success\", command, result: { message: result } }));\n  }\n}\n\nfunction encrypt(message, password) {\n\t// Encryption logic\n}\n```\n\nIf the worker will use a third-party library, it can be imported as an ES module, but don't forget to install it using:\n\n```bash\ndart run flutter_node_worker install \u003cpackage-name\u003e --dir my_worker\n```\n\n*or:*\n\n```bash\ncd my_worker\nnpm install \u003cpackage-name\u003e\n```\n\n##### Worker Response Format\n\u003e The worker **must return a `String` representation of a `Map`** (i.e., a JSON object).  \n\u003e This response **must include a `status` field**, which should be either `\"success\"` or `\"error\"`.\n\nUse `JSON.stringify()` to serialize your result before sending it:\n\n```js\n// ✅ Correct: sending a valid JSON string with required `status` field\npostMessage(JSON.stringify({\n  status: \"success\",\n  data: {\n    encrypted: \"abc123\"\n  }\n}));\n\n// ❌ Incorrect: sending a raw object (will fail in Dart)\npostMessage({\n  status: \"success\",\n  data: {\n    encrypted: \"abc123\"\n  }\n}); // ❌ Will cause an error — Dart expects a String\n\n// ❌ Incorrect: missing `status` field\npostMessage(JSON.stringify({\n  data: {\n    encrypted: \"abc123\"\n  }\n}));\n```\n\nIn Dart, this response will be automatically parsed with `jsonDecode()` into a `Map\u003cString, dynamic\u003e`. The `status` field is used to determine whether the operation was successful or resulted in an error.\n\n#### 3. Build a module worker\n\n```bash\ndart run flutter_node_worker build --dir my_worker --out-dir ../web/workers\n```\n\n_or:_\n\n```bash\ncd my_worker\nnpm run build\n```\n\nCreates 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.  \nFor example, if your worker is in `my_worker`, use `--out-dir=../web/workers`.\n\n---\n\n#### 4. Use a worker in Flutter Web\n\n```dart\nfinal worker = FlutterNodeWorker(path: \"my_worker/dist/encryptor_module.js\");\n\nfinal result = await worker.compute(\n  command: \"encrypt\",\n  data: {\"message\": \"Hello\", \"password\": \"secret\"},\n);\n```\n\n---\n\n## 🧩 Structure\n\n```text\nmy_worker/\n├── package.json\n├── vite.config.js\n├── src/\n│   └── encryptor.js       // Your worker logic\n├── dist/\n│   └── encryptor_module.js  // Compiled worker module\n```\n\n---\n\n## 📚 API\n\n### `FlutterNodeWorker`\n\n```dart\nFlutterNodeWorker({required String path})\n```\n\n#### Methods\n\n- `compute({command, data, computeOnce})`  \n    Sends a command and data to the worker and returns the result.\n    \n    - 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.\n        \n    - If `computeOnce = false`, the worker remains active, which is suitable for frequent tasks such as encrypting chat messages.\n\t\n    - `timeoutDuration` — a `Duration` specifying the maximum amount of time to wait for a response from the worker. If no response is received within this period, a `TimeoutException` will be thrown.\n        \n- `terminate()`  \n    Manually terminates the worker, freeing up resources.\n    \n\n---\n\n## CLI-commands\n\nEach command can be run in **one of three ways**:\n\n| Method      | Example                                                              |\n| ----------- | -------------------------------------------------------------------- |\n| `dart run`  | `dart run flutter_node_worker init --dir my_worker --name encryptor` |\n| Bash script | `./fnw init --dir my_worker --name encryptor`                        |\n| Makefile    | `make init dir=my_worker name=encryptor`                             |\n\n---\n\n### `init` — Generate worker template\n\n```bash\ndart run flutter_node_worker init --dir my_worker --name encryptor\n./fnw init --dir my_worker --name encryptor\nmake init dir=my_worker name=encryptor\n```\n\n---\n\n### `build` — Build worker module via Vite\n\n```bash\ndart run flutter_node_worker build --dir my_worker --out-dir ../web/workers\n./fnw build --dir my_worker --out-dir ../web/workers\nmake build-worker dir=my_worker out-dir=../web/workers\n```\n\nThe `--out-dir` should be specified **relative to the worker's directory**, not the project root.  \nFor example, if your worker is in `my_worker`, use `--out-dir=../web/workers`.\n\n---\n\n### `add` — Add new worker script\n\n```bash\ndart run flutter_node_worker add --dir my_worker --name decryptor\n./fnw add --dir my_worker --name decryptor\nmake add dir=my_worker name=decryptor\n```\n\n---\n\n### `install` — Install npm package to worker\n\n```bash\ndart run flutter_node_worker install uuid --dir my_worker\n./fnw install uuid --dir my_worker\nmake install dir=my_worker pkgs=uuid\n```\n\n---\n\n### `uninstall` — Remove npm package\n\n```bash\ndart run flutter_node_worker uninstall uuid --dir my_worker\n./fnw uninstall uuid --dir my_worker\nmake uninstall dir=my_worker pkgs=uuid\n```\n\n---\n\n### CLI Arguments\n\n| Argument    | Abbreviation | Description                                                                   |\n| ----------- | ------------ | ----------------------------------------------------------------------------- |\n| `--dir`     | `-d`         | The directory in which the command is executed (`init`, `build`, `add`, etc.) |\n| `--name`    | `-n`         | Worker name when initializing or adding a new one                             |\n| `--out-dir` | `-o`         | Directory where the compiled module will be placed                            |\n\n---\n\n## 🛠️ Dependencies\n\n- [Node.js](https://nodejs.org/)\n    \n- [Vite](https://vitejs.dev/)\n    \n- [cli_util](https://pub.dev/packages/cli_util)\n    \n- [args](https://pub.dev/packages/args)\n    \n- [mustache_template](https://pub.dev/packages/mustache_template)\n    \n- [dart:js_interop](https://dart.dev/web/js-interop)\n\t\n- [path](https://pub.dev/packages/path)\n\n- [talker](https://pub.dev/packages/talker)\n    \n\n---\n\n## 🖼️ Demo\n\nThe demo application allows you to encrypt and decrypt a message using a password.\nFor clarity, an animation has been added demonstrating that the main thread is not blocked - the UI remains responsive even when performing heavy operations.\n\nBy opening DevTools → **Sources → Threads**, you can see the active threads, including the Web Worker (`cipher_module.js`), where the calculation takes place.\n\n[CHECK WEB DEMO](https://flutter-node-worker-demo.web.app/)\n\n---\n\n## 🤝 Support\n\nOpen an issue or pull request. Any help is appreciated!\n\n---\n\n## 🤝 Contributors\n\nThanks to all these amazing people:\n\n[![Contributors](https://contrib.rocks/image?repo=printHelloworldd/flutter-node-worker)](https://github.com/printHelloworldd/flutter-node-worker/graphs/contributors)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprinthelloworldd%2Fflutter-node-worker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprinthelloworldd%2Fflutter-node-worker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprinthelloworldd%2Fflutter-node-worker/lists"}