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

@varunkanwar/atelier

v0.1.1

Published

A task runtime for browser workloads with parallelism, backpressure, and cancellation

Readme

Atelier

npm version npm downloads license

Atelier is a browser-only task runtime for Web Worker workloads that need predictable concurrency, backpressure, and cancellation without adopting a pipeline DSL. It is intentionally small: a runtime, task proxies, and two executors backed by a shared queue.

Use it when you have CPU-heavy or bursty work in the browser and you need to control how much work is in flight and what happens under load. It does not try to schedule across tasks or define a pipeline language; those decisions stay with your app.

Installation

bun add @varunkanwar/atelier
# or
npm install @varunkanwar/atelier

Quick start

Main thread:

import { createTaskRuntime } from '@varunkanwar/atelier'

type ResizeAPI = {
  process: (image: ImageData) => Promise<ImageData>
}

const runtime = createTaskRuntime()

const resize = runtime.defineTask<ResizeAPI>({
  type: 'parallel',
  worker: () => new Worker(new URL('./resize.worker.ts', import.meta.url), { type: 'module' }),
  keyOf: image => image.docId,
  timeoutMs: 10_000,
})

const result = await resize.process(image)

Worker:

import { expose } from 'comlink'
import { createTaskWorker, type TaskContext, type StripTaskContext } from '@varunkanwar/atelier'

const handlers = {
  async process(image: ImageData, ctx: TaskContext) {
    ctx.throwIfAborted()
    return resized
  },
}

export type ResizeAPI = StripTaskContext<typeof handlers>
expose(createTaskWorker(handlers))

How it works

Each task call flows through a DispatchQueue that enforces maxInFlight and maxQueueDepth. A call moves through three phases: waiting (call-site blocked before admission), pending (accepted but not dispatched), and in-flight (running on a worker). When the queue is full, the policy determines whether callers wait, are rejected, or are dropped.

For pipeline-level flow control, parallelLimit caps concurrency across a set of items without introducing a DSL. It pairs well with queue backpressure to avoid large intermediate allocations.

Cancellation and timeouts

If you provide a keyOf function, AbortTaskController can cancel all queued and in-flight work for a given key. timeoutMs creates an AbortSignal per call and is treated like cancellation. Cancellation can happen while waiting, queued, or in-flight; the worker harness exposes __cancel so handlers can cooperate.

const runtime = createTaskRuntime()
const resize = runtime.defineTask<ResizeAPI>({ /* ... */, keyOf: image => image.docId })

const promise = resize.process(image) // image.docId === 'doc-123'
runtime.abortTaskController.abort('doc-123')
await promise

Zero-copy transfers

Atelier automatically transfers common large data types (ArrayBuffer, ImageData, ImageBitmap, streams, etc.) to avoid structured cloning. You can override that per call:

// Disable transfer for debugging or to keep ownership
await resize.with({ transfer: [] }).process(imageData)

// Selective transfer
await colorCorrect.with({ transfer: [image.data.buffer] }).process(image, lut)

// Keep the result in the worker
await encoder.with({ transferResult: false }).addFrame(frame)

Transfers move ownership: the sender’s buffers become detached. Clone first if you need to keep the original.

Observability

The runtime exposes a state snapshot API plus an event stream for metrics, spans and traces. Spans are opt-in and sampled; events are emitted only when listeners are registered.

const runtime = createTaskRuntime({
  observability: { spans: { mode: 'auto', sampleRate: 1 } },
})

const unsubscribe = runtime.subscribeEvents(event => {
  // MetricEvent | SpanEvent | TraceEvent
})

Docs

  • Design notes: https://github.com/VarunKanwar/atelier/blob/main/docs/design/README.md
  • Observability model: https://github.com/VarunKanwar/atelier/blob/main/docs/design/observability.md
  • API reference (curated and published at /docs/ on the site)
  • Testing: https://github.com/VarunKanwar/atelier/blob/main/docs/testing.md
  • Demo site (scenarios and UI): https://github.com/VarunKanwar/atelier/tree/main/apps/site

Development

bun install
bun run test
bun run check:fix