Vize

use-worker-fn

Build the worker script for fn.

Package @vizejs/composable/use-worker-fn
Own the source vize lib pull composable:use-worker-fn
Runtime exports createWorkerFnScript, useWorkerFn
Gzip budget 3328 B

Minimal setup

Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).

vp install @vizejs/composable

Import the entry directly. Call lifecycle-bound utilities inside <script setup> so cleanup follows the component scope; consult the runtime contract for this entry's SSR and hydration behavior.

import { createWorkerFnScript, useWorkerFn } from "@vizejs/composable/use-worker-fn";

Try it

Run a heavy calculation in a worker

Move a CPU-heavy pure function off the main thread without writing a worker file.

Open the interactive example

What to observe: Count primes runs in a worker and reports 17984 primes found in a worker while the page stays responsive.

The function is serialized into the worker, so it cannot use variables from the component scope. Pass timeoutMs to stop runaway work.

Compare the initial and interacted states
Run a heavy calculation in a worker: initial state
Initial state
Run a heavy calculation in a worker: state after the verified interactions
After the verified interactions

Copy the example

Save this complete SFC in your Vue project. Its public imports and source are the same ones executed in the preview.

<script setup lang="ts">
import { ref } from "vue";
import { useWorkerFn } from "@vizejs/composable/use-worker-fn";

function countPrimes(limit: number): number {
  let count = 0;
  for (let candidate = 2; candidate <= limit; candidate += 1) {
    let prime = true;
    for (let divisor = 2; divisor * divisor <= candidate; divisor += 1) {
      if (candidate % divisor === 0) {
        prime = false;
        break;
      }
    }
    if (prime) count += 1;
  }
  return count;
}

const { status, run } = useWorkerFn(countPrimes);
const result = ref<number>();

async function calculate() {
  result.value = await run(200_000);
}
</script>

<template>
  <div class="composable-example">
    <p>Run a heavy calculation in a worker so the page stays responsive.</p>
    <button type="button" :disabled="status === 'running'" @click="calculate">
      Count primes up to 200,000
    </button>
    <output aria-live="polite">{{
      result === undefined ? `Worker status: ${status}` : `${result} primes found in a worker`
    }}</output>
  </div>
</template>

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
createWorkerFnScript performance experimental safe not-applicable none web, server, worker, native, desktop, terminal — —
useWorkerFn performance experimental deterministic-fallback stable caller, reactive-scope web, desktop Blob, globalThis, window createWorkerFnScript, tryOnScopeDispose

API

createWorkerFnScript

Build the worker script for fn. Exposed for inspection and testing. The function source is embedded with Function.prototype.toString, so it must be self-contained: no closures over module variables, only its arguments, localDependencies, dependencies, and worker globals.

function createWorkerFnScript( fn: (...arguments_: never[]) => unknown, options: Pick<UseWorkerFnOptions, "dependencies" | "localDependencies"> = {}, ): string

useWorkerFn

Run a CPU-heavy function in a dedicated Blob-URL worker, off the main thread. Each run spawns a fresh worker, posts the arguments, and resolves with the function's (awaited) result; the worker is terminated and its URL revoked once the run settles, times out, or is terminated. Concurrent runs reject with VIZE_COMPOSE_WORKER_FN_BUSY. The running worker is terminated when the owning reactive scope stops. Server rendering never spawns workers: supported is false and run rejects with VIZE_COMPOSE_WORKER_FN_UNSUPPORTED.

function useWorkerFn<Arguments extends readonly unknown[], Result>( fn: (...arguments_: Arguments) => Result, options: UseWorkerFnOptions = {}, ): WorkerFnControls<Arguments, Result>
const { run, status } = useWorkerFn((values: number[]) =>
  [...values].sort((a, b) => a - b),
);
const sorted = await run(bigArray);

Types

WorkerLike

Minimal dedicated worker used by useWorkerFn.

Member Type Description
postMessage (message: unknown) => void Send a structured-clonable message to the worker.
terminate () => void Stop the worker immediately.
addEventListener (type: "message" | "messageerror" | "error", listener: EventListener) => void Subscribe to message, messageerror, or error.
removeEventListener (type: "message" | "messageerror" | "error", listener: EventListener) => void Remove a listener registered with addEventListener.

WorkerFnHost

Capabilities needed to run a function in a Blob-URL worker.

Member Type Description
Worker WorkerConstructorLike Worker constructor (e.g. Worker).
createObjectURL (script: Blob) => string Create a URL for the generated worker script (e.g. URL.createObjectURL).
revokeObjectURL (url: string) => void Release a URL returned by createObjectURL.

UseWorkerFnOptions

Options for useWorkerFn.

Member Type Description
timeoutMs? number Reject and terminate a run after this many milliseconds.
dependencies? readonly string[] Absolute script URLs loaded with importScripts before the function runs.
localDependencies? readonly ((...arguments_: never[]) => unknown)[] Named standalone functions inlined into the worker so fn can call them.
host? MaybeRefOrGetter<WorkerFnHost | null | undefined> Worker capabilities for alternate runtimes and tests.
scheduler? TimeoutScheduler Timer host for timeoutMs.

WorkerFnControls

Reactive state and controls returned by useWorkerFn.

Member Type Description
status Readonly<Ref<WorkerFnStatus>> Lifecycle status of the latest run.
supported Readonly<Ref<boolean>> Whether worker capabilities are available.
run (...arguments_: Arguments) => Promise<Awaited<Result>> Run the function in a fresh worker. Arguments and result must be structured-clonable. Rejects with a tagged Error whose message starts with a WorkerFnErrorCode.
terminate () => void Terminate the running worker, rejecting its pending run.