โ† Back to Portal
๐Ÿฆ€ Rust WASM โšก AssemblyScript โœจ Simplified API

WASM Integration Guide

Run Monte Carlo simulations in the browser with just 3 lines of code

โšก Quick Start

๐ŸŽ‰ It's Now Super Simple!

Configuration is embedded in the WASM binary. No config loading, no initialization calls. Just load the module and run!

3 Steps to Run a Simulation

๐Ÿ“ฆ
Load WASM
โ†’
๐Ÿš€
Call Simulation
โ†’
๐Ÿ“Š
Get Results

That's it! No config files to load. No initialization functions to call. The WASM binary contains everything it needs.

๐ŸŽฏ Minimal Example (Tier 1)

Start with just age and income. The engine infers everything else from demographic data.

JavaScript - Complete Working Example
// Step 1: Load the WASM module
const rustJS = await import('/static/wasm/rust/flash_simulate_rust.js');
const wasmResp = await fetch('/static/wasm/rust/flash_simulate_rust_bg.wasm');
await rustJS.default(await wasmResp.arrayBuffer());

// Step 2: Generate z-scores (deterministic RNG)
const trials = 1000, years = 40;
const zScores = rustJS.generate_z_scores(BigInt(42), trials * years);

// Step 3: Run simulation with MINIMAL input (just age + income!)
const input = {
    current_age: 35,
    income: 100000,
    // Everything else is INFERRED by the engine:
    // - Retirement age (67)
    // - Savings (from demographics)
    // - Tax rates (from state)
    // - Social Security (calculated)
    // - Life expectancy (from actuarial tables)
};

const result = rustJS.run_simulation_tiered(
    JSON.stringify(input),
    zScores,
    '[]',  // life_events
    '[]',  // real_assets
    '[]',  // liabilities
    2026   // base_year
);

// Get percentiles
const percentiles = rustJS.compute_percentiles(result, trials, years);
console.log('Median terminal wealth:', percentiles.p50[years - 1]);
โœ… That's the entire integration!

No init_config(). No add_federal_bracket(). No loading 6 config files. The engine handles it all internally.

๐Ÿ“Š Progressive Disclosure (Tiers)

Provide more data for more accurate results. The engine always fills in what's missing.

Tier User Provides Engine Infers
Tier 1 (HOOK) Age + Income Everything else (savings, state, allocation, SS, life expectancy)
Tier 2 (ENGAGE) + Total savings, state Account splits, allocation, tax rates
Tier 3 (QUALIFY) + Account breakdown Tax optimization parameters

Tier 2 Example

JavaScript
const input = {
    current_age: 35,
    income: 100000,
    total_savings: 150000,    // User provides savings
    state_code: "CA",          // Higher state tax
    retirement_age: 62,        // Early retirement
};

Tier 3 Example (Full Account Breakdown)

JavaScript
const input = {
    current_age: 45,
    income: 180000,
    state_code: "TX",           // No state tax
    filing_status: "married",
    retirement_age: 60,
    
    // Explicit account breakdown (Tier 3)
    taxable: 200000,           // Brokerage account
    tax_deferred: 450000,      // 401(k) + IRA
    roth: 100000,              // Roth IRA
    cost_basis_ratio: 0.7,     // 70% cost basis in taxable
    
    // Spouse
    spouse_age: 43,
    spouse_income: 95000,
    spouse_retirement_age: 62,
};

๐Ÿ“‹ Input Reference

All fields except current_age and income are optional.

Field Type Default Description
current_age number required Current age
income number required Annual gross income
total_savings number inferred Total savings (if not providing account breakdown)
state_code string "US_AVG" Two-letter state code
retirement_age number 67 Target retirement age
filing_status string inferred "single" or "married"
sex string "unknown" "male", "female", or "unknown" (for life expectancy)
taxable number inferred Taxable account balance (-1 = infer)
tax_deferred number inferred 401(k)/IRA balance (-1 = infer)
roth number inferred Roth IRA balance (-1 = infer)
spouse_age number 0 Spouse age (0 = no spouse)
spouse_income number 0 Spouse annual income

โšก AssemblyScript Alternative

AssemblyScript provides the same API with a slightly different loading pattern:

JavaScript
// Load AssemblyScript module
const asModule = await import('/static/wasm/assemblyscript/simulate.js');

// Generate z-scores
const zScores = asModule.generateZScores(BigInt(42), trials * years);

// Run tiered simulation
const result = asModule.runSimulationTiered(
    35,        // current_age
    100000,    // income
    0,         // total_savings (0 = infer)
    "",        // state_code ("" = infer)
    0,         // retirement_age (0 = infer)
    "",        // filing_status
    "",        // sex
    -1,        // taxable (-1 = infer)
    -1,        // tax_deferred
    -1,        // roth
    -1,        // cost_basis_ratio
    0,         // spouse_age
    0,         // spouse_income
    0,         // spouse_retirement_age
    1000,      // trials
    40,        // years
    0,         // combined_contribution (0 = infer)
    zScores,   // z-scores
    2026       // base_year
);

๐Ÿฆ€ Rust WASM

  • Speed: ~6ms (fastest)
  • API: JSON input
  • Best for: Production

โšก AssemblyScript

  • Speed: ~15ms
  • API: Positional args
  • Best for: TypeScript teams

๐ŸŽฒ Deterministic RNG

Both engines use PCG32 + Box-Muller for deterministic random number generation. Same seed = same results.

JavaScript
// Generate z-scores with a seed for reproducibility
const seed = 42;
const count = trials * years;  // 1000 * 40 = 40,000

// Rust
const zScores = rustJS.generate_z_scores(BigInt(seed), count);

// AssemblyScript
const zScores = asModule.generateZScores(BigInt(seed), count);
โœ… 0.00% Variance

With the same seed and inputs, Rust WASM, AssemblyScript WASM, and Python produce identical results across all 30+ test scenarios.