Reference
SSR / Nuxt
useWorker/useWorkerComputed/useWorkerPool are safe to call in setup() on the server — the constructor is passed as a factory (() => new Worker(...)) and only invoked from inside run(), i.e. only on the client in normal usage. If run() is nonetheless called during SSR, you get a WorkerUnavailableError with a clear message rather than a crash. Guard client-only usage with <ClientOnly> in Nuxt:
<ClientOnly>
<ProgressBar v-if="isRunning" :value="progress" />
</ClientOnly>Bundler support
No worker-loader/worker-plugin or other webpack-era workarounds needed — this uses the native ESM worker import (new URL('./x.worker.ts', import.meta.url) + { type: 'module' }), which Vite (and Nuxt 3/4) picks up and bundles as its own chunk automatically. If you're on classic Webpack (Vue CLI), you'll need worker-plugin or equivalent — that's a bundler limitation, not this package's.
Benchmark Suite
npm run benchmark (benchmark/heavy-computation.bench.ts, via tinybench) compares a CPU-bound task (naive recursive fib(30..34)) run on the main thread vs. a single worker thread vs. a 4-thread pool — via node:worker_threads, since this runs under Node (tsx), not a browser. It's a sanity check of the pool's real parallel speedup, not a benchmark of this package's own composables (those add negligible overhead on top of raw postMessage, which is what's actually being measured here).
Example run on this machine (results vary by hardware/load — run it yourself for numbers that mean anything on your machine):
| Task | Ops/sec | Avg time |
|---|---|---|
| Main thread | 7.4 | 135ms |
| Single worker thread | 5.8 | 173ms |
| Pool of 4 worker threads | 9.1 | 111ms |
Single-worker is slower than main thread here — expected: postMessage/thread-startup overhead on a task that isn't parallelized. The pool is faster because 8 tasks genuinely run across 4 threads at once, not because any one worker is faster than the main thread.
Comparison
vue-worker (latest 1.2.1, published 2017) and vue-web-workers (latest 0.2.0, published 2020, depends on vue@^2.6.11 directly) are both effectively unmaintained Vue 2 plugins — verified against the npm registry, not from memory. Comlink (4.4.2, still actively maintained, zero dependencies) is a solid, Vue-agnostic RPC layer.
vue-worker / vue-web-workers | Comlink | vue-worker-kit | |
|---|---|---|---|
| Composition API | ✗ | — (not Vue-specific) | ✓ |
| Typed input/output | ✗ | manual wrap<T>() | inferred from the worker file |
| Worker pool | ✗ | ✗ | ✓ (createWorkerPool, pool.map with per-item transfer) |
| Reactive computed-in-worker | ✗ | ✗ | ✓ (useWorkerComputed) |
| SharedWorker (multi-tab) | ✗ | ✗ | ✓ (useSharedWorker) |
| Streaming results | ✗ | ✗ | ✓ (ctx.reportChunk, chunks.value) |
| Cancellation | ✗ | ✗ | ✓ (AbortSignal, per-task + global for pool) |
| Transferables | ✗ | ✓ (manual, both directions) | ✓ (RunOptions.transfer in, ctx.transfer() out, per-item for pool.map) |
| Worker warmup | ✗ | ✗ | ✓ (warmup() for single worker and pool) |
| Retry with backoff | ✗ | ✗ | ✓ (configurable delay function) |
| Result caching (LRU) | ✗ | ✗ | ✓ (cache: 'lru', maxCacheSize) |
| SSR-safe | ✗ | — | ✓ |
| Dependencies | — | none | none beyond vue |
License
MIT