Skip to content

Architecture

Para’s two products (Lang and Runtime) ship code across two npm-vs-binary namespaces. The split tells a reader at a glance whether an import is portable or needs the Runtime:

  • @para/* — nine cross-runtime libraries on npm. Pure JS / Wasm, no native dependencies. They run anywhere JS does — Node, Deno, Bun, browsers, ParaBun. This is most of Lang’s runtime surface.
  • parabun:* — twelve native modules linked into the ParaBun binary. They wrap codec stacks, GPU compute, and hardware I/O — work that pure JS can’t match. Only available when running on ParaBun.

Both share the same import shape, so you don’t have to think about which side you’re on:

import signals from "@para/signals"; // anywhere
import image from "parabun:image"; // Parabun

When you’re on Parabun, @para/* libraries quietly use their parabun:* counterparts under the hood — where one exists. Same import, faster impl, no code change to opt in.

parabun:* modules are native, hardware-accelerated, and only available in the Parabun runtime. @para/* libraries are cross-runtime, available on npm, and automatically use their parabun:* counterpart when running on Parabun.

Module@para/*parabun:*What it does
signalsReactive state — Signal / Computed / Effect
parallelplannedWorker pool — pmap / preduce / psort + Mutex / Semaphore
arenaBuffer pool + JSC-GC-deferring scope()
lifecycleProcess-state coordination — keepAlive with SIGINT/SIGTERM + onShutdown hook
simdplannedSIMD over typed arrays — sum, dot, matVec, topK
csvplannedRFC 4180 parse / stringify
arrowplannedIn-memory Arrow + IPC + Parquet
rtpRFC 3550 RTP packets + jitter buffer
mcpModel Context Protocol client (stdio + WebSocket)
imageJPEG / PNG / WebP / AVIF / HEIC / JPEG-XL — decode, encode, filters
videoH.264 / H.265 / VP9 / AV1 — decode, encode, thumbnails, extract audio
audioWAV / MP3 / FLAC / AAC / OGG / Opus + ALSA capture / playback
llmLlama / Mistral / Whisper inference on CUDA + Metal
visionFrame analysis — motion, YOLO, OCR, ONNX runtime
speechVoice activity detection + Whisper STT + Piper TTS
assistantTurn-taking voice agent over speech + llm
gpuCUDA + Metal compute — matVec, conv2D, scan, reduce, histogram
gpioLinux GPIO — digital in/out, edge events
i2cLinux I²C with SMBus convenience
spiLinux SPI with multi-segment transfers
cameraV4L2 frame capture

How to read it at a glance:

  • Both columns filled → portable library that gets faster on Parabun.
  • — in @para/* → Parabun-only. System codecs, GPU, and kernel drivers don’t have a credible browser/Node equivalent.
  • — in parabun:* → pure JS is already as fast as native here, so we don’t ship one.
  • planned → on the roadmap. The @para/* library works today; the native fast path is tracked but not yet shipped.

Two more npm packages back Para language features:

PackageBacks which feature
@para/pipeline|> operator runtime + affine-chain compile()
@para/decimalExact-decimal arithmetic for 0.1d literals

These modules compose. A few realistic shapes:

  • Streaming ETL@para/csv + @para/arrow parse a multi-GB CSV and write per-country Parquet without loading the file into memory. Works in Node today; faster on Parabun once the native CSV parser lands.
  • Voice assistantsparabun:speech + parabun:llm + parabun:audio give you a wake-word → STT → LLM → TTS loop in 30 lines. Parabun-only because the engines need GPU.
  • IoT control loopsparabun:gpio + @para/signals make a reactive sensor → threshold → relay loop on a Raspberry Pi. The same @para/signals powers the React dashboard you serve from the device.
  • In-browser data tools@para/arrow + @para/parallel slice a Parquet file and run worker-pooled aggregates on the user’s machine, no server round-trip.

See Examples for runnable code.

Two namespaces, two distribution stories:

  • @para/* ships on npm and is meant to be portable. You can install one of them in a Node project that’s never heard of Parabun, and everything works.
  • parabun:* ships inside the Parabun binary and links against system libraries (codecs, CUDA, V4L2, SPI). It can’t be npm installed because most environments don’t have what it needs.

Keeping them in separate namespaces means a developer reading code can tell at a glance which side an import is on — parabun: is the “you need Parabun for this” tell, @para/ is the “this works anywhere” tell. The cross-runtime promise stays unambiguous.