Skip to content

TypeScript quickstart

The TypeScript SDK ships four packages on npm. The convenience meta-package mostlyright re-exports the surfaces you usually want; the scoped packages (@mostlyrightmd/core, @mostlyrightmd/weather, @mostlyrightmd/markets) let you depend on exactly what you need.

The current published version is 0.1.0-rc.7 on the next dist-tag. The non-rc 0.1.0 final ships shortly after the Python 0.1.0 ships.

Terminal window
pnpm add mostlyright@next

Node 18+. The package is ESM-first with CJS fallback. Both import and require work; types ship in the same package.

If you only need the weather fetchers (no markets, no core re-exports), depend on @mostlyrightmd/weather directly:

Terminal window
pnpm add @mostlyrightmd/weather@next @mostlyrightmd/core@next
import { research } from "mostlyright";
const rows = await research("KNYC", "2025-01-06", "2025-01-12");
console.log(rows[0]);

research() returns Promise<ReadonlyArray<PairsRow>> — a frozen array with one row per LST settlement date in [fromDate, toDate]. Each row carries:

type PairsRow = {
date: string; // YYYY-MM-DD (LST)
station: string; // 3-letter NWS code
cli_high_f: number | null;
cli_low_f: number | null;
cli_report_type: string | null;
obs_high_f: number | null;
obs_low_f: number | null;
obs_mean_f: number | null;
obs_mean_dewpoint_f: number | null;
obs_max_wind_kt: number | null;
obs_max_gust_kt: number | null;
obs_total_precip_in: number | null;
obs_count: number;
// ... plus fcst_* (all null in Mode 1) and market_close_utc
};

cli_* comes from the NWS CLI overnight final (the Kalshi NHIGH/NLOW settlement source). obs_* comes from the merged METAR feed: AWC > IEM > GHCNh on tie-break.

The Node cache writes JSON envelopes (not parquet — parquet is a Python-only choice) to ~/.mostlyright/cache-ts/:

~/.mostlyright/cache-ts/
├── observations/{ICAO}/{YYYY}/{MM}.json
└── climate/{ICAO}/{YYYY}.json

Override the root with MOSTLYRIGHT_CACHE_DIR:

Terminal window
export MOSTLYRIGHT_CACHE_DIR=/data/mostlyright

The Python SDK uses cache/v1/ and the TS SDK uses cache-ts/ under the same root, so they never overwrite each other.

For live METAR ticks, use the stream() async generator from @mostlyrightmd/weather:

import { stream } from "@mostlyrightmd/weather";
for await (const row of stream("KNYC")) {
console.log(row.observed_at, row.temp_f);
}

Pass an AbortSignal to interrupt cleanly:

import { stream } from "@mostlyrightmd/weather";
const controller = new AbortController();
setTimeout(() => controller.abort(), 60_000);
for await (const row of stream("KNYC", { signal: controller.signal })) {
console.log(row.observed_at, row.temp_f);
}

stream() never writes the cache. It dedups by observed_at so AWC’s “latest METAR” repeats between observation cycles collapse to one row per fresh tick.

@mostlyrightmd/core is the only package designed for browser bundles — it ships under a 25 KB size budget. The weather and markets packages depend on Node-only modules (node:fs, node:path for the cache) and should not be bundled for the browser.

For a browser-side call, fetch JSON from your own backend that wraps research(), then validate with @mostlyrightmd/core/validator:

import { validateRows } from "@mostlyrightmd/core/validator";
const response = await fetch("/api/research?station=KNYC&from=2025-01-06&to=2025-01-12");
const rows = await response.json();
const result = validateRows(rows, "schema.observation.v1");
  • Temporal safetyKnowledgeView for point-in-time filtering, assertNoLeakage for the audit path.
  • Source identity — Mode 1 vs Mode 2, SourceMismatchError.
  • Legacy migration — there is no legacy TS package; this is a first install.