Skip to content

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.

Terminal window
pnpm add mostlyright
pnpm add @mostlyrightmd/markets

The packages are public on npm. They do not require a copied vendor bundle.

SourceDirect browser request
AWC live weatherAllowed
IEM CLI daily summariesAllowed
IEM ASOS archiveBlocked
GHCNh / NCEI archiveBlocked
Polymarket Gamma, CLOB, and Data APIAllowed
KalshiRejected 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.

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.

A worker can keep parsing and IndexedDB work off the UI thread. It does not change which providers the browser can reach.

worker.ts
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),
});
}
});

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.

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.

RuntimeDefault store
Browser / MV3IndexedDB
Node 20+Filesystem under $HOME/.mostlyright/cache-ts/
Storage-less edge runtimeIn memory

Advanced cache classes live under @mostlyrightmd/core/internal/cache. They are unsupported internals and may change without notice.