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.
01 · Install
Section titled “01 · Install”pnpm add mostlyright@nextnpm install mostlyright@nextyarn add mostlyright@nextNode 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:
pnpm add @mostlyrightmd/weather@next @mostlyrightmd/core@next02 · First call
Section titled “02 · First call”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.
03 · Cache layout
Section titled “03 · Cache layout”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}.jsonOverride the root with MOSTLYRIGHT_CACHE_DIR:
export MOSTLYRIGHT_CACHE_DIR=/data/mostlyrightThe Python SDK uses cache/v1/ and the TS SDK uses cache-ts/ under the same root, so they never overwrite each other.
04 · Live streaming
Section titled “04 · Live streaming”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.
05 · Browser usage
Section titled “05 · Browser usage”@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");What to read next
Section titled “What to read next”- Temporal safety —
KnowledgeViewfor point-in-time filtering,assertNoLeakagefor the audit path. - Source identity — Mode 1 vs Mode 2,
SourceMismatchError. - Legacy migration — there is no legacy TS package; this is a first install.