Feature Request: WebAssembly (WASM) Build Target
Summary
Add a wasm Cargo feature flag that enables the finance-query library to compile to wasm32-unknown-unknown, making it usable in browsers (via wasm-pack), Node.js, Cloudflare Workers, and Deno. The primary challenge is the Yahoo Finance cookie-based authentication flow, which requires a different approach in WASM contexts; the proposed solution uses conditional compilation to route around the native cookie jar while preserving full functionality.
Problem Statement
The library is currently native-only. Every consumer surface — server, CLI, MCP — runs as a native binary. This excludes a large and growing class of use cases:
- Browser-based dashboards that want to query financial data client-side without a backend.
- Cloudflare Workers / edge functions that need financial data without the overhead of a full server.
- VS Code extensions and other Electron-based tools built on Node.js.
- Deno scripts and Jupyter notebooks running in a JavaScript runtime.
The only workaround today is to host the FinanceQuery HTTP server and proxy all requests through it — adding operational overhead for use cases that could run entirely in-process.
Proposed Solution
Feature Flag and Dependency Changes
# Cargo.toml
[features]
wasm = ["dep:wasm-bindgen", "dep:wasm-bindgen-futures", "dep:web-sys", "dep:js-sys"]
[dependencies]
wasm-bindgen = { version = "0.2", optional = true }
wasm-bindgen-futures = { version = "0.4", optional = true }
web-sys = { version = "0.3", optional = true, features = ["Window", "Performance"] }
js-sys = { version = "0.3", optional = true }
# reqwest: swap to fetch backend on WASM, no cookies feature
[target.'cfg(target_arch = "wasm32")'.dependencies]
reqwest = { version = "0.13", features = ["json"] } # no cookies, no gzip
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
reqwest = { version = "0.13", features = ["json", "cookies", "gzip"] }
The Authentication Problem and Solution
The native auth flow (src/auth.rs) uses reqwest's cookie_store(true) to persist Yahoo Finance session cookies across requests, then fetches a CSRF crumb token. Neither cookie_store nor std::time::Instant are available in WASM.
In a browser context, cookies are managed automatically by the browser's cookie jar — the fetch API (which reqwest uses under the hood on WASM) inherits the browser's cookie state. The crumb request still works via fetch; the session cookie is handled transparently.
In a non-browser WASM context (Workers, Deno), there is no cookie jar. The solution is to accept a pre-fetched crumb and cookie string as optional client configuration, bypassing the automated auth flow:
// src/client.rs
#[derive(Default)]
pub struct ClientConfig {
pub timeout: Duration,
pub proxy: Option<String>,
// New: pre-supplied auth for WASM non-browser contexts
#[cfg(feature = "wasm")]
pub wasm_crumb: Option<String>,
#[cfg(feature = "wasm")]
pub wasm_cookie: Option<String>,
}
Conditional compilation gates the two auth paths:
// src/auth.rs
#[cfg(not(target_arch = "wasm32"))]
pub async fn authenticate(config: &ClientConfig) -> Result<YahooAuth> {
// existing native flow: cookie_store + crumb fetch
}
#[cfg(target_arch = "wasm32")]
pub async fn authenticate(config: &ClientConfig) -> Result<YahooAuth> {
// browser: fetch crumb via fetch API, browser handles cookies
// worker: use pre-supplied crumb/cookie from config
}
std::time::Instant is replaced with #[cfg] guards — WASM uses js_sys::Date::now() for elapsed-time tracking.
JavaScript / TypeScript Usage
After wasm-pack build --target web (browser) or wasm-pack build --target bundler (Node/Workers):
import init, { Ticker, Tickers } from "finance-query-wasm";
await init(); // load WASM module
// Single ticker
const ticker = await Ticker.new("AAPL");
const quote = await ticker.quote();
console.log(quote.shortName, quote.regularMarketPrice);
// Batch
const tickers = await Tickers.new(["AAPL", "MSFT", "TSLA"]);
const quotes = await tickers.quotes();
// Chart data
const chart = await ticker.chart("1d", "1mo");
The wasm-bindgen layer exposes Ticker and Tickers with async methods that return JavaScript objects (serialized via serde-wasm-bindgen or serde_json).
Feature Availability in WASM vs Native
| Feature |
WASM Browser |
WASM Workers |
Native |
quote, chart, news, search |
✓ |
✓ |
✓ |
options, financials, transcripts |
✓ |
✓ |
✓ |
indicators (pure computation) |
✓ |
✓ |
✓ |
risk (pure computation) |
✓ |
✓ |
✓ |
backtesting |
✓ |
✓ |
✓ |
fred |
✓ |
✓ |
✓ |
crypto |
✓ |
✓ |
✓ |
rss |
✓ |
✓ |
✓ |
dataframe (polars) |
✗ |
✗ |
✓ |
translation (trad) |
✗ |
✗ |
✓ |
| Proxy support |
✗ |
✗ |
✓ |
dataframe and translation are excluded from WASM — polars does not target WASM, and trad's offline inference engine requires native CPU features. Both are behind their own feature flags so the exclusion is clean.
npm Package Publishing
wasm-pack build --target bundler --out-name finance-query
npm publish pkg/
This publishes an npm package finance-query-wasm with TypeScript type definitions auto-generated from the wasm-bindgen annotations.
Use Cases
- Browser dashboard — a React/Vue portfolio tracker queries live quotes and chart data client-side via the WASM library, with no backend required and no CORS proxy.
- Cloudflare Worker — an edge function provides financial data to a mobile app with <5 ms cold starts, using the pre-supplied crumb/cookie config for auth.
- VS Code extension — a market data sidebar in a Rust/finance-focused IDE extension, built on Node.js using the npm package.
- Deno Jupyter notebook — financial analysis in a notebook environment using the Deno WASM runtime, mixing Rust-backed data fetching with JavaScript charting libraries.
Alternatives Considered
- Python bindings via PyO3 — complementary, not an alternative. A
python feature flag using PyO3 could be a separate feature request and would cover Jupyter in CPython. WASM covers browser and edge runtimes that PyO3 cannot.
- C FFI (
cbindgen) — enables use from any language via C bindings but requires native compilation. Does not cover browser/edge use cases.
- Server-side proxy (existing workaround) — works today but adds infrastructure overhead, latency, and a single point of failure for every WASM consumer.
Additional Context
- Bundle size: the WASM binary will be substantial due to async runtime and HTTP client code.
wasm-opt (run automatically by wasm-pack) typically reduces size 30–40%. A --features wasm build without indicators/risk/backtesting produces a minimal bundle suitable for simple quote/news use cases.
- Threading: WASM's threading model requires
SharedArrayBuffer, which is behind COOP/COEP headers in browsers. The library's Arc<RwLock<T>> caches will use std::sync on native and the single-threaded WASM equivalents on WASM (no Send + Sync issues since all async work goes through the JS event loop).
- WASM SIMD: the
indicators and risk computation features can benefit from WASM SIMD instructions (wasm32 target with simd128 feature) for floating-point heavy operations. Opt-in via a build flag.
- No breaking changes: the
wasm feature is purely additive. Native compilation is unaffected.
Priority
Feature Request: WebAssembly (WASM) Build Target
Summary
Add a
wasmCargo feature flag that enables thefinance-querylibrary to compile towasm32-unknown-unknown, making it usable in browsers (viawasm-pack), Node.js, Cloudflare Workers, and Deno. The primary challenge is the Yahoo Finance cookie-based authentication flow, which requires a different approach in WASM contexts; the proposed solution uses conditional compilation to route around the native cookie jar while preserving full functionality.Problem Statement
The library is currently native-only. Every consumer surface — server, CLI, MCP — runs as a native binary. This excludes a large and growing class of use cases:
The only workaround today is to host the FinanceQuery HTTP server and proxy all requests through it — adding operational overhead for use cases that could run entirely in-process.
Proposed Solution
Feature Flag and Dependency Changes
The Authentication Problem and Solution
The native auth flow (
src/auth.rs) usesreqwest'scookie_store(true)to persist Yahoo Finance session cookies across requests, then fetches a CSRF crumb token. Neithercookie_storenorstd::time::Instantare available in WASM.In a browser context, cookies are managed automatically by the browser's cookie jar — the
fetchAPI (whichreqwestuses under the hood on WASM) inherits the browser's cookie state. The crumb request still works viafetch; the session cookie is handled transparently.In a non-browser WASM context (Workers, Deno), there is no cookie jar. The solution is to accept a pre-fetched crumb and cookie string as optional client configuration, bypassing the automated auth flow:
Conditional compilation gates the two auth paths:
std::time::Instantis replaced with#[cfg]guards — WASM usesjs_sys::Date::now()for elapsed-time tracking.JavaScript / TypeScript Usage
After
wasm-pack build --target web(browser) orwasm-pack build --target bundler(Node/Workers):The
wasm-bindgenlayer exposesTickerandTickerswithasyncmethods that return JavaScript objects (serialized viaserde-wasm-bindgenorserde_json).Feature Availability in WASM vs Native
quote,chart,news,searchoptions,financials,transcriptsindicators(pure computation)risk(pure computation)backtestingfredcryptorssdataframe(polars)translation(trad)dataframeandtranslationare excluded from WASM — polars does not target WASM, andtrad's offline inference engine requires native CPU features. Both are behind their own feature flags so the exclusion is clean.npm Package Publishing
This publishes an npm package
finance-query-wasmwith TypeScript type definitions auto-generated from thewasm-bindgenannotations.Use Cases
Alternatives Considered
pythonfeature flag using PyO3 could be a separate feature request and would cover Jupyter in CPython. WASM covers browser and edge runtimes that PyO3 cannot.cbindgen) — enables use from any language via C bindings but requires native compilation. Does not cover browser/edge use cases.Additional Context
wasm-opt(run automatically bywasm-pack) typically reduces size 30–40%. A--features wasmbuild withoutindicators/risk/backtestingproduces a minimal bundle suitable for simple quote/news use cases.SharedArrayBuffer, which is behind COOP/COEP headers in browsers. The library'sArc<RwLock<T>>caches will usestd::syncon native and the single-threaded WASM equivalents on WASM (noSend+Syncissues since all async work goes through the JS event loop).indicatorsandriskcomputation features can benefit from WASM SIMD instructions (wasm32target withsimd128feature) for floating-point heavy operations. Opt-in via a build flag.wasmfeature is purely additive. Native compilation is unaffected.Priority