Skip to content

TypeScript / Node SDK ​

Native Node.js bindings for the Kairos real-time options analytics engine, powered by napi-rs. Every call crosses one language boundary into the same Rust analytics code path the core uses — no Python bridge, no subprocess overhead, no second analytic implementation to maintain.

The TypeScript SDK is the third runtime Kairos ships, alongside the Rust core and the Python facade. The cross-SDK performance numbers are published in PERF.

Prerequisites ​

  • Node 20 or newer.
  • An account with the upstream options-market data feed Kairos is wired against. The SDK authenticates via Credentials(email, password) or Credentials.fromEnv() (reads THETADATA_EMAIL / THETADATA_PASSWORD).

Install ​

sh
npm install kairos-thetadata

The TypeScript / Node addon is distributed privately at this stage; the package resolves against the in-house registry rather than the public npm registry. The snippet above shows the install shape consumers will use once public release is enabled.

The package builds pre-built native binaries for:

  • linux-x64-gnu
  • darwin-arm64
  • win32-x64-msvc

The native binaries link against the same Rust core that drives the Python facade and the Rust crate; the in-house tarball carries the pre-built binaries for the supported platforms.

Connect ​

typescript
import { Client, Credentials } from "kairos-thetadata";

const creds = Credentials.fromEnv();
const client = await Client.connect(creds);

Client.connectOffline() is the in-tree test path — it boots the engine without an upstream session. Live subscribes against an offline client surface a typed [ConnectionError] rejection.

Subscribe to your first analytic ​

OHLCVC is the simplest one-minute introduction. Run the analytic via client.live().ohlcvc([...]) and register a callback with .onEvent; it returns a handle with .unsubscribe():

typescript
import { Client, Credentials } from "kairos-thetadata";

const client = await Client.connect(Credentials.fromEnv());

const sub = await client
  .live()
  .ohlcvc(["QQQ"])
  .onEvent((bar) => {
    console.log(
      `${bar.symbol}: O=${bar.open} H=${bar.high} L=${bar.low} ` +
      `C=${bar.close} V=${bar.volume}`,
    );
  });

The analytic accessor argument is polymorphic — pass a bare ticker string (or a list) for the full chain, or option-spec objects ({ root, expiration, right, strike }) for individual contracts. The two shapes mix in the same list. The wire-internal contract integer is never exposed; option contracts are identified by their public 4-tuple throughout.

Historical query (Arrow IPC) ​

The historical surface returns an Arrow IPC byte buffer per query — column-oriented, ready for apache-arrow to read on the JS side:

typescript
import { Client, Credentials } from "kairos-thetadata";
import { RecordBatchStreamReader } from "apache-arrow";

const client = await Client.connect(Credentials.fromEnv());

const ipcBytes = await client
  .historical()
  .ohlcvc(["QQQ"])
  .query(20260105, 20260109);

const reader = RecordBatchStreamReader.from(ipcBytes);
for (const batch of reader) {
  console.log(`rows=${batch.numRows}`);
}

The Rust core, Python facade, and TypeScript SDK all return the same schema for the same (analytic, contract universe, date range) query.

Bound analytics ​

The TypeScript SDK binds the full analytic catalogue — all 139 analytics across the six families. The per-analytic binding is generated from the same descriptor inventory the Rust core registers, so the TypeScript surface tracks the catalogue with no per-analytic hand-maintenance: each analytic exposes a client.live().<analytic>() builder (camelCase), its <Name>Params.default(filter) spec constructor, and its tick type, alongside the symbol-first accessor argument, the forIndex / forSector universe selectors, and the documented onEvent consumption path.

See the analytics catalogue for the full list grouped by family; each analytic's page documents its generated spec and tick field tables. The naming convention is mechanical:

ConceptTypeScript shape
Builderclient.live().<analyticCamel>() — e.g. greeks(), marketTide(), vpin()
Spec<Name>Params.default(filter) — e.g. GreeksParams, VpinParams
Tick<Name>Tick — e.g. GreekTick, OhlcvcBar, OpenInterestFlowTick
Universeaccessor argument (symbol / list / option tuple / mixed) plus forIndex / forSector
Consume.onEvent(callback) → handle with .unsubscribe()

Error handling ​

Every binding-side error is prefixed with a typed class tag the JS side can pattern-match:

  • [ConnectionError] ... — upstream unreachable.
  • [AuthenticationError] ... — credentials rejected.
  • [SpecValidationError] ... — invalid params or contract identifier.
  • [SubscribeError] ... — subscription-time engine state failure.
  • [HistoricalQueryError] ... — historical query failure.
  • [StreamError] ... — live-stream lag / disconnect.

Replay against a recorded parquet dataset is part of the Rust + Python surfaces today; the TypeScript surface picks it up in a follow-up release.

Next steps ​

  • Analytics catalogue — every analytic, methodology citation, and worked example.
  • API reference — Spec / Tick types, builders, errors.
  • Methodology — Black-Scholes, Lee-Ready, CBOE VIX, VPIN, SqueezeMetrics references.

Proprietary. All rights reserved.