Zero-copy iframe data transport — Apache Arrow bundled, no setup required
window
CONNECTING
child-alpha
CONNECTING
child-beta
CONNECTING
No messages yet. Send data or click Reply in a child iframe.
Code examples
import { ArrowParentEmitter, tableFromArrays, tableToIPC } from 'iframe-flight'; const emitter = new ArrowParentEmitter(iframe); emitter.onReady(async () => { // send() picks the best transfer automatically: // Uint8Array + SAB → sendArrowZeroCopy (zero-copy ⚡) // Uint8Array → sendArrowCopy (postMessage) // anything else → sendJSON const table = tableFromArrays({ id: [1,2,3], name: ['Alice','Bob','Charlie'] }); const ack = await emitter.send(tableToIPC(table)); console.log(ack.rows, ack.isZeroCopy); // Plain object → always JSON await emitter.send({ userId: 42, action: 'refresh' }); });
API reference
send(data, opts?)Auto — zero-copy → copy → JSON⭐sendJSON(data, opts?)Any JSON-serialisable valuesendArrowCopy(buf)Arrow IPC via postMessagesendArrowZeroCopy(buf)Arrow IPC via SharedArrayBuffer ⚡onReady / onStateChange / onErrorLifecycle hooksisSABSupported() / getState()Introspectionclose()Reject pending ACKs, cleanuponData(cb)result.table (Arrow) or result.data (JSON)resumeListening()Re-enable after FIRST_MESSAGEonStateChange / onError / close()Same as emittertableFromArrays(cols)Create Arrow table from arraystableToIPC / tableFromIPCSerialize / deserializeA minimal working example — parent sends a table, child receives it. That's it.
<!-- parent.html — no npm install needed --> <script type="importmap"> {"imports": {"iframe-flight": "https://ihatexcel.github.io/iframe-flight/iframe-flight.esm.js"}} </script> <script type="module"> import { ArrowParentEmitter, tableFromArrays, tableToIPC } from 'iframe-flight'; const emitter = new ArrowParentEmitter(document.querySelector('iframe')); emitter.onReady(async () => { const table = tableFromArrays({ id: [1, 2, 3], name: ['Alice', 'Bob', 'Charlie'], score: [95.5, 87.3, 92.1], }); const ack = await emitter.send(tableToIPC(table)); console.log(`rows=${ack.rows} zeroCopy=${ack.isZeroCopy}`); }); </script>
<!-- child.html — same CDN, no install --> <script type="importmap"> {"imports": {"iframe-flight": "https://ihatexcel.github.io/iframe-flight/iframe-flight.esm.js"}} </script> <script type="module"> import { ArrowChildReceiver } from 'iframe-flight'; const receiver = new ArrowChildReceiver(); receiver.onData((result) => { // result.table → Apache Arrow Table // result.data → plain JS value (JSON mode) console.log(result.table.toArray()); }); </script>
Push columnar data from your app into an embedded chart widget — no shared state, no coupling. The parent generates an Arrow table; the child renders it live with Vega-Lite.
import { ArrowParentEmitter, tableFromArrays, tableToIPC } from 'iframe-flight'; const PRODUCTS = ['Aurora', 'Beacon', 'Catalyst', 'Dynamo', /* … */]; function makeSnapshot(n) { const products = PRODUCTS.slice(0, n); const revenue = Float64Array.from(products.map(() => rand(10, 100))); const growth = Float64Array.from(products.map(() => rand(-25, 25))); const units = Int32Array.from(products.map(() => randInt(5000, 50000))); return tableToIPC(tableFromArrays({ product: products, revenue, growth, units })); } const emitter = new ArrowParentEmitter(iframe); emitter.onReady(async () => { const ack = await emitter.send(makeSnapshot(10)); console.log(`${ack.rows} rows · ${ack.processingTime}ms`); });
import { ArrowChildReceiver } from 'iframe-flight'; const receiver = new ArrowChildReceiver({ allowedOrigins: ['*'] }); receiver.onData(result => { // Convert Arrow columnar → row objects const rows = []; const t = result.table; for (let i = 0; i < t.numRows; i++) { const row = {}; t.schema.fields.forEach((f, ci) => { row[f.name] = t.getChildAt(ci).get(i); }); rows.push(row); } // Render with Vega-Lite — works with any Arrow schema vegaEmbed('#chart', { data: { values: rows }, mark: { type: 'bar', cornerRadiusEnd: 4 }, encoding: { y: { field: 'product', sort: '-x' }, x: { field: 'revenue', type: 'quantitative' }, color: { field: 'growth', scale: { scheme: 'redyellowgreen' } } } }, { actions: false }); });
Single-file pattern — the child iframe is injected via srcdoc, no separate HTML file needed. Copy the source and open it directly in a browser.
embed.html
embed.html
Loading…