corelib

A modern foundation for multi-runtime TypeScript.

Resilient HTTP, structured logging and a native Rust streaming core — one toolkit that behaves the same on Node, Bun and Deno.

HTTP / Logging / FFI / Markets / Cloud

Native

Rust engine, zero event-loop blocking.

Typed

Strict signatures, no any.

Modular

Take one package or all three.

Open source

MIT, developed in the open.

quickstart.ts
// Retries, jitter, typed results — built in.
import { endPoint } from "@ckirg/corelib";

const res = await endPoint("/me");

if (res.status === "success") {
  console.log(res.value.status, res.value.body);
} // typed union
What's in the box

Three packages. One native core.

Each package is published on its own, but they share the same config, logger and FFI bridge. Install only what you need.

@ckirg/corelib

The foundation: resilient HTTP, structured logging, config, database helpers and the FFI loader.

  • endPoint / endPoints with retry + full jitter
  • RequestProxied with self-healing proxy pools
  • Child logger with cycle-safe error serialization
pnpm add @ckirg/corelibAPI →

@ckirg/corelib-markets

Market data plumbing for Nasdaq, Yahoo, Alpaca and Finnhub, plus the CNN Fear & Greed sentiment index.

  • AlpacaStreaming · YahooStreaming · FinnhubStreaming
  • Historical and NasdaqPolling data feeds
  • MarketMonitor for phase + status tracking
pnpm add @ckirg/corelib-marketsAPI →

@ckirg/corelib-cloud

Edge routers for AWS, GCP and Cloudflare — including the transparent single-URL proxy.

  • createRouter for Hono on the edge
  • kyRouter · nasdaqRouter · sqlRouter
  • Same response shape as the local client
pnpm add @ckirg/corelib-cloudAPI →
Native core

Rust does the waiting.

WebSockets and streaming live in a N-API module. Frames arrive on Rust worker threads and reach JS as events — the event loop never blocks.

  • 01Prebuilt binaries. A postinstall picks the right .node for your OS and arch from the matching release.
  • 02Same API everywhere. Node, Bun and Deno all load the same bridge, with a typed events surface.
  • 03Resilience built in. Silence detection, keep-alive and reconnect are handled below the JS layer.
napi bridgelive
Rust worker
WS client

Alpaca · Yahoo · Finnhub

ThreadsafeFunctionno block
JS runtime
EventEmitter

pricing · market · log · error

HTTP that retries itself

Every request gets a correlation id, a timeout floor and full-jitter backoff. 5xx, network failures and 429 retry; other 4xx stops immediately. You get a discriminated union back, not a thrown error.

// retries: 5 · timeout: 50s · jitter const res = await endPoint("/me", { retry: { limit: 5 } })
attempt timeline

Logs you can actually parse

One child logger per module, a strict (msg, extras?) signature, and errors serialized depth-first with cycle detection. At LOG_LEVEL=trace you can reconstruct the whole decision chain.

const log = logger.child({ section: "retry" }) log.debug("retry decision", { status, willRetry })
stdout · tracejson

Cloud routers, transparent by default

The edge proxy returns the target's body and status directly for a single URL, and an array of results for bulk. Deploy it to Cloudflare, AWS or GCP with the same router code.

import { createRouter } from "@ckirg/corelib-cloud" export default createRouter()
edge topologysingle hop
client
GET /ky?url=…

one URL → passthrough

edgehono
origin
200 · body

same status, same headers

Quickstart

Three commands to a typed request.

The install step is the same shape on every runtime. Nothing else is required to make your first call.

1

Install

Add the core package. Markets and cloud are separate, opt-in installs.

pnpm add @ckirg/corelib
2

Make a request

Retries, jitter and a typed result — no wrapper to write.

import { endPoint }
  from "@ckirg/corelib";

const r = await endPoint(url);
3

Stream a quote

Native FFI stream, events delivered on the JS side.

import { AlpacaStreaming }
  from "@ckirg/corelib-markets";

const stream = new AlpacaStreaming();
stream.on("pricing", (tick) => {
  console.log(tick.symbol);
});

Every type and signature is documented.

The full API reference is generated from the source on every push to main — three packages and the Rust core, one index.

Generated from source on every push to main