# Knitting > Knitting is a zero-dependency, shared-memory concurrency runtime for Node.js, Deno, and Bun. Move typed JavaScript work to threads, separate processes, or browser workers and call it like an async function. Use Knitting when CPU-heavy, bursty, or isolation-sensitive work should leave the main thread without becoming a separate service. Its compact API combines typed calls with shared-memory IPC, work stealing, timeouts, cancellation, worker permissions, and zero-copy paths for large binary payloads. Its scheduling defaults are built to keep the CPU cost of threading low rather than to maximize a benchmark number: idle workers park instead of spinning, and on supported runtimes the host waits on a doorbell instead of polling, so a pool that is not saturated costs close to nothing while it waits. Knitting is Apache-2.0 open source on [GitHub](https://github.com/mimiMonads/knitting). Its [test suite](https://github.com/mimiMonads/knitting/tree/main/test) covers runtime behavior, shared-memory transport, process workers, work stealing, permissions, package output, browser execution, and compiled workers. [Continuous integration](https://github.com/mimiMonads/knitting/actions/workflows/test.yml) exercises Node.js, Deno, and Bun across a multi-OS matrix, with a [90% Node line-coverage gate](https://github.com/mimiMonads/knitting/actions/workflows/coverage.yml). Use the links below to find the documentation relevant to your question. For broad architectural or repository-wide work, fetch [llms-full.txt](https://knittingdocs.vercel.app/llms-full.txt) for the complete documentation; most implementation questions only need a few targeted pages. **Essentials** - Install: `npm install knitting` (the npm package is `knitting`; it is also on JSR as `@vixeny/knitting`). Requires Node 22+, Deno 2+, or Bun 1+. - A task is an exported function at module scope. Wrap it with `task({ f })` only when you want options like a timeout or an abort signal. - Tasks take ONE argument. Use a tuple or object for multiple values: `([a, b]) => a + b`. - Guard host-only code with `isMain` — workers re-import the module. - Module loading: each worker re-imports the module that DEFINES your tasks, and its top-level `import`s run in every worker (they are hoisted — `isMain` does NOT gate them). Keep tasks in a lean module separate from your server/framework code. Tasks must be `export`ed or the loader can't find them and the call silently hangs. `importTask` targets must be plain functions, not `task()` wrappers. - Create a pool with `createPool(options)({ taskA, taskB })`, then call `await pool.call.taskA(args)`. - Scheduling: compatible multi-worker pools use native work stealing by default. Workers claim tasks from a shared submit region while keeping private return lanes; control it with `host.steal`, `host.stealRegionLanes`, and `host.doorbell`. The task API does not change, and unsupported runtimes fall back to private lanes or polling. - Idle cost is a design goal: waiting threads are not allowed to burn CPU. A single worker spins 50us before parking because it is on the request's critical path; multi-worker pools park immediately, since a peer is already awake to take the work. The host doorbell replaces polling wake-ups on Node and Bun thread pools. Expect a bigger pool to raise CPU per request without raising throughput when the host is the only producer (a server), so size `threads` from measurements, not from core count — see the Multi-threading guide. - Cleanup: `using pool = createPool(...)` disposes the pool at scope exit. `await pool.shutdown()` still exists to close it earlier or to await teardown. - Isolation: `importTask({ href, name })` keeps a task's code off the host (only the worker imports it). Set `worker.runtime: "process"` to run each worker as a separate process — including inside a bwrap sandbox or a container. - Security: `importTask` prevents the task module from being imported or evaluated at host scope, but it is not a sandbox. For genuinely untrusted code, use process workers with an OS sandbox or container and restrictive permissions; runtime permissions are guardrails, not a complete security boundary. - Zero-copy IN: `ProcessSharedBuffer` (`knitting/shared-memory`) shares bytes across processes; `SharedArrayBuffer` and `BufferReference` (`knitting/unsafe`) move bytes to thread workers without copying. Pick by boundary — process vs thread. - Binary results: for large results from a thread worker, RETURN a `BufferReference`; owning Node addons can move them back zero-copy, while the safe default may take one copy on Deno/Bun (use the explicit borrow mode only when its lifetime rules fit). `knitting/utils` converts string/JSON/number ↔ `SharedArrayBuffer`. - Optimized for HTTP: `call.*()` accepts `Promise` inputs, so forward `request.arrayBuffer()` (e.g. Hono `c.req.arrayBuffer()`) straight into a task without awaiting it on the request thread — UTF-8 decode / JSON parse then happens in the worker. Ideal for SSR, JWT, and upload routes. - Workers are quiet by default: in strict mode worker `console.*` does NOT reach the host — set `permission: { console: true }` to surface it. Common direct exit calls (`process.exit`, `process.kill`, `process.abort`, and `Deno.exit`) are blocked, but this is not a complete security boundary; resource exhaustion and runtime or native-code vulnerabilities still require OS-level isolation. - Debugging goes to STDERR: pass `debug: true` to `createPool` (or set the `KNITTING_DEBUG=*` env var) to stream diagnostics, each line tagged with the worker (`host`, `w0`, `w1`, …), the runtime, and a per-worker ms timer. Select namespaces instead of all — `host` (pool/task setup), `imports` (which modules each worker loaded), `lifecycle` (worker ready / process events), `signals` (per-dispatch traffic, very chatty), `globals` (`globalThis` pollution per load phase) — via `debug: { host: true, imports: true }` or `KNITTING_DEBUG=host,imports`. The option and the env var merge; either can enable a namespace. Zero-cost when off: the logger module isn't even imported. - Payload size: dynamic payloads are hard-capped at ~8 MiB by default (over-cap calls reject with `KNT_ERROR_3`). Raise it with `payload: { maxPayloadBytes, payloadMaxByteLength }` — `maxPayloadBytes` must be `<= payloadMaxByteLength >> 3`; the buffer growth cap defaults to 64 MiB. - Cancellation & timeouts: `task({ f, timeout: { time: 100 } })` bounds a call, `task({ f, abortSignal: true })` injects an abort toolkit (`signal.hasAborted()`, `signal.now()`) as the task's second argument — it is NOT a DOM `AbortSignal` (no `.aborted`, no `addEventListener`, cannot be passed to `fetch`) — and `worker.hardTimeoutMs` is a hard wall-clock kill for runaway CPU. - Browser: `knitting/browser` runs the same pool API on web workers. Two hard requirements: the page must be cross-origin isolated (`Cross-Origin-Opener-Policy: same-origin` plus `Cross-Origin-Embedder-Policy: require-corp`, or `createPool` throws), and every task module must call `setModuleUrl(import.meta.url)` before defining tasks, because stack-based module discovery needs V8's `Error.prepareStackTrace`, which Firefox and Safari do not have. Not available in a page: process workers, compiled/Porffor workers, `BufferReference`, `ProcessSharedBuffer`, and passing a `SharedArrayBuffer` as a task argument. `permission: {...}` is accepted but IGNORED — a web worker holds the full privileges of the page that started it. - Errors are real: thrown errors and rejected promises return to the host as `Error` objects with `name`, `message`, `stack`, and the full `cause` chain. ```ts import { createPool, isMain } from "knitting"; export const square = (n: number) => n * n; export const greet = (name: string) => `hello ${name}`; if (isMain) { // `using` shuts the pool down when this block ends. using pool = createPool({ threads: 2 })({ square, greet }); const [n, msg] = await Promise.all([ pool.call.square(8), pool.call.greet("knitting"), ]); console.log({ n, msg }); // { n: 64, msg: "hello knitting" } } ``` ## Getting Started - [Installation](https://knittingdocs.vercel.app/start/installation/): Install Knitting from npm for Node.js, Deno, and Bun, and verify runtime requirements for shared-memory worker IPC. - [Quick Start](https://knittingdocs.vercel.app/start/quick-start/): Build your first Knitting pool: define tasks, call them like async functions, run them in parallel, and shut down cleanly. ## Guides - [Defining tasks](https://knittingdocs.vercel.app/guides/defining-tasks/): A task is a function your workers run. Use a plain function for the simple case, or task() when you want timeouts, aborts, or imported worker code. - [Creating pools](https://knittingdocs.vercel.app/guides/creating-pools/): Every createPool option in one place: threads, balancers, work stealing, the inliner lane, payload buffers, permissions, debug namespaces, and shutdown. - [Payloads](https://knittingdocs.vercel.app/guides/payloads/): The data types you can pass into a task and return from one. - [Buffer utilities](https://knittingdocs.vercel.app/guides/utils/): knitting/utils — helpers for serializing strings, JSON, and numbers into SharedArrayBuffer and back. - [Permissions](https://knittingdocs.vercel.app/guides/permissions/): Control what worker tasks can read, write, import, and run. - [Process workers](https://knittingdocs.vercel.app/guides/process-workers/): Run each worker as a separate OS process for stronger isolation — through a sandbox like bubblewrap or a container like Docker. - [Shared memory](https://knittingdocs.vercel.app/guides/shared-memory/): ProcessSharedBuffer — the lower-level shared-memory channel for passing bytes between workers and processes without copying. - [Buffer reference](https://knittingdocs.vercel.app/guides/buffer-reference/): Move large ArrayBuffers to thread workers without copying. - [Performance](https://knittingdocs.vercel.app/guides/performance/): How payloads, worker counts, and runtime choices affect performance. - [Inliner](https://knittingdocs.vercel.app/guides/inliner/): Run pure compute on the host thread as an extra lane. - [Multi-threading](https://knittingdocs.vercel.app/guides/multi-threading/): Choose a worker count for HTTP services and CPU-bound batch work without starving the host thread. - [Compiled workers](https://knittingdocs.vercel.app/guides/compiled-workers/): Compile supported tasks into native Porffor workers. - [Browser](https://knittingdocs.vercel.app/guides/browser/): Run Knitting in a browser — download the build, see what works over web workers, and learn what a page cannot do. - [Work stealing](https://knittingdocs.vercel.app/guides/work-stealing/): How compatible multi-worker pools share one submit region so idle workers can claim waiting tasks. ## Examples - [Examples](https://knittingdocs.vercel.app/examples/intro_examples/): Worked examples you can copy into a real project. - [Data transforms](https://knittingdocs.vercel.app/examples/data_transforms/intro_data_transforms/): Validation, rendering, and output examples — pick the one closest to your workload. - [Big prime](https://knittingdocs.vercel.app/examples/maths/big_prime/): Search for large primes in parallel with a Miller-Rabin test. - [React SSR](https://knittingdocs.vercel.app/examples/data_transforms/rendering_output/react_ssr/): Render React components to HTML strings on workers, away from the request thread. - [Schema validate](https://knittingdocs.vercel.app/examples/data_transforms/validation/schema_validate/): Validate JSON payloads against a Zod schema on workers. - [JWT revalidation](https://knittingdocs.vercel.app/examples/data_transforms/validation/jwt_revalidation/): Verify JWTs and reissue them with Web Crypto, without an external JWT library. - [Monte Carlo pi](https://knittingdocs.vercel.app/examples/maths/monte_pi/): Estimate pi by throwing darts at a circle, split across workers. - [React SSR compression](https://knittingdocs.vercel.app/examples/data_transforms/rendering_output/react_ssr_compress/): Render React on a worker and Brotli-compress the HTML, measuring where the compression step belongs. - [Markdown to HTML](https://knittingdocs.vercel.app/examples/data_transforms/rendering_output/markdown_to_html/): Convert markdown to HTML and Brotli-compress it in the same worker call. - [Physics loop](https://knittingdocs.vercel.app/examples/maths/physics_loop/): A branch-heavy 2D random-walk simulation spread across workers. - [Salt hashing](https://knittingdocs.vercel.app/examples/data_transforms/validation/salt_hashing/): PBKDF2 password hashing with constant-time verification, kept off the request thread. - [Hono server routes](https://knittingdocs.vercel.app/examples/data_transforms/rendering_output/hono_server/): Build a Hono server with ping, SSR, and JWT routes in Knitting or host-only mode. - [Prompt token budgeting](https://knittingdocs.vercel.app/examples/data_transforms/validation/prompt_token_budgeting/): Trim LLM prompts to fit a token budget before sending them to any model. - [TSP (GSA)](https://knittingdocs.vercel.app/examples/maths/tsp_gsa/): Parallel heuristic restarts for a gravity-inspired TSP solver. ## Benchmarks - [Benchmarks](https://knittingdocs.vercel.app/benchmarks/introduction/): Knitting benchmark results across Node.js, Deno, and Bun, with the hardware and methodology behind them. - [Node.js](https://knittingdocs.vercel.app/benchmarks/node/): Knitting on Node.js: message overhead, a head-to-head with a plain worker, latency as calls grow, heavy-task efficiency, and payload type costs. - [Deno](https://knittingdocs.vercel.app/benchmarks/deno/): Knitting on Deno: message overhead, a head-to-head with a plain worker, latency as calls grow, heavy-task efficiency, and payload type costs. - [Bun](https://knittingdocs.vercel.app/benchmarks/bun/): Knitting on Bun: message overhead, a head-to-head with a plain worker, latency as calls grow, heavy-task efficiency, and payload type costs. - [Tokio](https://knittingdocs.vercel.app/benchmarks/tokio/): How Knitting compares with Tokio on small values, large payloads, and shared byte buffers. ## Extras - [Why Knitting](https://knittingdocs.vercel.app/extras/why/): Why Knitting exists: move hot JavaScript functions off the main thread without turning them into services. - [Architecture](https://knittingdocs.vercel.app/extras/architecture/): How Knitting's shared-memory transport, mailbox protocol, and lane model fit together. ## Source and verification - [GitHub repository](https://github.com/mimiMonads/knitting): Knitting's implementation, releases, issue tracker, and Apache-2.0 license. - [Test suite](https://github.com/mimiMonads/knitting/tree/main/test): Runtime, IPC, process-worker, scheduling, permissions, package, browser, and compiled-worker tests. - [Continuous integration](https://github.com/mimiMonads/knitting/actions/workflows/test.yml): Node.js, Deno, and Bun testing across a multi-OS matrix, plus browser end-to-end checks. - [Coverage workflow](https://github.com/mimiMonads/knitting/actions/workflows/coverage.yml): Node.js line coverage enforced at 90% or higher. - [Documentation source](https://github.com/mimiMonads/knittingdocs): Source for this documentation site and its generated llms files. ## Full text - [llms-full.txt](https://knittingdocs.vercel.app/llms-full.txt): every documentation page inlined into one file.