npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mileszim/useworker-vite

v4.2.0

Published

Vite plugin for @mileszim/useworker — run worker functions composed from imports across files and npm packages, just like passing a pure function.

Readme

@mileszim/useworker-vite

A Vite plugin for @mileszim/useworker that lets you write your worker function across multiple modules and npm packages and invoke it exactly like passing a pure function.

Why

useWorker(fn) moves fn into a Web Worker by stringifying it (fn.toString()). That captures only the source text of that one function — any variable from its closure or any imported binding is not included, so a worker function that references other modules throws ReferenceError at runtime:

import { square } from './math'
const compute = (xs) => xs.map(square) // `square` is undefined inside the worker
useWorker(compute) // ❌ ReferenceError: square is not defined

The import graph that square came from was resolved and discarded by your bundler — it doesn't exist at runtime. The only place it does exist is at build time, which is what this plugin hooks into.

How it works

  1. You put worker code in a *.worker.{js,ts,jsx,tsx} module and import it normally.
  2. The plugin redirects that import to a generated proxy whose named exports are tagged refs understood by useWorker.
  3. Each ref is backed by Vite's native ?worker, so the bundler compiles the worker module's entire import graph (local files and npm packages) into a dedicated module-worker chunk.
  4. A tiny RPC dispatcher is appended to the worker so its exports are callable over postMessage.

useWorker detects the tagged ref and routes to this module-worker path instead of the blob/toString path — so the call site is unchanged.

Install

npm install @mileszim/useworker
npm install -D @mileszim/useworker-vite

Setup

// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { useworkerVite } from '@mileszim/useworker-vite'

export default defineConfig({
  plugins: [react(), useworkerVite()],
})

Usage

// transforms.worker.ts
import Papa from 'papaparse' // npm dep — bundled into the worker
import { square } from './math' // local import — bundled into the worker

export const compute = (xs: number[]) => xs.map(square)
export const parseCsv = (text: string) => Papa.parse(text).data
import { useWorker } from '@mileszim/useworker'
import { compute } from './transforms.worker'

function Example() {
  const [computeWorker] = useWorker(compute) // reads like a pure function

  const run = async () => {
    const result = await computeWorker([1, 2, 3]) // runs off the main thread
    console.log(result)
  }
  // ...
}

Because TypeScript resolves ./transforms.worker to the real source, compute keeps its real type signature — argument and return types are inferred at the call site. (At runtime it is a tagged ref; the plugin makes that swap safe.)

Options

useworkerVite({
  // Which modules are treated as worker modules.
  include: /\.worker\.[mc]?[jt]sx?$/, // default
  // Modules to exclude even if they match `include`.
  exclude: undefined,
})

Limitations

  • Named exports only. Export worker functions as named exports (export const fn = …), not export default.
  • Worker modules must be statically importable (a normal import), so the plugin can find them at build time.
  • Standard Web Worker constraints still apply: no window/document access, arguments and results must be structured-cloneable, and a worker function can't return a function.

Testing

The runtime behavior is verified end-to-end in a real browser (jsdom cannot execute workers) across both dev and production builds:

pnpm --filter @mileszim/useworker-vite test

Point CHROME_PATH at a Chrome/Chromium binary if it isn't at the default macOS location.