Browser integration
The TypeScript SDK includes browser-targeted bundles. Whether a call works directly from a page still depends on the upstream provider: Polymarket allows browser requests, while Kalshi rejects requests carrying a non-Kalshi origin.
Install
Section titled “Install”pnpm add mostlyrightpnpm add @mostlyrightmd/marketsThe packages are public on npm. They do not require a copied vendor bundle.
Browser reach by source
Section titled “Browser reach by source”| Source | Direct browser request |
|---|---|
| AWC live weather | Allowed |
| IEM CLI daily summaries | Allowed |
| IEM ASOS archive | Blocked |
| GHCNh / NCEI archive | Blocked |
| Polymarket Gamma, CLOB, and Data API | Allowed |
| Kalshi | Rejected by the venue |
A page, Web Worker, and Service Worker all obey the provider’s network policy.
Chrome extension host_permissions can help when only browser CORS enforcement
blocks a request. They cannot bypass Kalshi’s server-side 403 response to a
non-Kalshi Origin.
Provider behavior can change. Recheck the upstream response headers before you make a long-lived deployment assumption.
Read Polymarket directly
Section titled “Read Polymarket directly”Every Polymarket market-data verb works from a browser page:
import { polymarketCandles, polymarketMarket,} from "@mostlyrightmd/markets/market-data";
const { rows: listing } = await polymarketMarket( "highest-temperature-in-nyc-on-may-29",);
const { rows: prices } = await polymarketCandles( "highest-temperature-in-nyc-on-may-29", { side: "Yes", interval: "1h", fromTime: new Date("2026-05-20T00:00:00Z"), toTime: new Date("2026-05-30T00:00:00Z"), },);Kalshi market-data calls need Node, an edge function that the venue accepts, or your own server. Do not route authenticated venue requests through a public client bundle.
Use a Web Worker
Section titled “Use a Web Worker”A worker can keep parsing and IndexedDB work off the UI thread. It does not change which providers the browser can reach.
import { weather } from "mostlyright";
self.addEventListener("message", async (event) => { const { station } = event.data;
try { const row = await weather.latest(station); self.postMessage({ ok: true, row }); } catch (error) { self.postMessage({ ok: false, error: error instanceof Error ? error.message : String(error), }); }});Use a server or edge function
Section titled “Use a server or edge function”Keep blocked source calls and durable credentials outside the browser:
import { kalshiCandles } from "@mostlyrightmd/markets/market-data";
export default { async fetch(): Promise<Response> { const result = await kalshiCandles("KXHIGHNY-26MAY29-T85", { interval: "1h", fromTime: new Date("2026-05-20T00:00:00Z"), toTime: new Date("2026-05-30T00:00:00Z"), }); return Response.json(result); },};Apply authentication, rate limits, and an allowlist before exposing a generic proxy. The SDK’s market-data reads themselves are read-only and do not place orders.
Hosted satellite delivery
Section titled “Hosted satellite delivery”Local Level 2 satellite decoding is not browser viable. Use the hosted weather consumer when your deployment has a short-lived or server-managed API key:
import { satelliteHosted } from "@mostlyrightmd/weather/hosted";
const rows = await satelliteHosted({ hostedUrl, apiKey, lat: 40.7789, lon: -73.9692, satellite: "goes16", fromTime: "2026-05-20T00:00:00Z", toTime: "2026-05-20T23:59:00Z",});Do not put a durable shared API key in a public page or extension bundle.
Runtime cache behavior
Section titled “Runtime cache behavior”| Runtime | Default store |
|---|---|
| Browser / MV3 | IndexedDB |
| Node 20+ | Filesystem under $HOME/.mostlyright/cache-ts/ |
| Storage-less edge runtime | In memory |
Advanced cache classes live under @mostlyrightmd/core/internal/cache. They
are unsupported internals and may change without notice.
See also
Section titled “See also”- Market data: venue verbs and normalized fields
- Weather observations: historical and live calls
- Satellite measurements: local and hosted paths
- Credentials: hosted environment variables