Inline Mode vs URL Mode in wren-core-wasm: A Complete Guide for Browser Queries

Inline mode requires pre-registering data buffers with registerParquet before calling loadMDL, while URL mode streams Parquet files on-demand via HTTP Range requests by passing a base URL to loadMDL.

The @wrenai/wren-core-wasm package from the Canner/WrenAI repository enables WebAssembly-based SQL querying directly in the browser through a semantic layer (MDL). When integrating this engine into client-side applications, developers must choose between two distinct data-loading strategies: inline mode for embedded datasets and URL mode for remote streaming. Understanding the difference between inline mode and URL mode in wren-core-wasm is critical for optimizing performance and server requirements.

How Inline Mode Works in wren-core-wasm

Inline mode operates by loading data entirely into the browser's memory before query execution. According to the source code in core/wren-core-wasm/README.md (lines 26-45), the application fetches data files—such as Parquet, CSV, or JSON—and registers them with the engine using explicit API calls.

The workflow requires calling registration methods before initializing the MDL:

import { WrenEngine } from '@wrenai/wren-core-wasm';

const engine = await WrenEngine.init();

// Register data buffers before loading MDL
await engine.registerJson('orders', [
  { id: 1, customer: 'Alice', amount: 100 },
  { id: 2, customer: 'Bob', amount: 200 },
]);

// Or register a Parquet buffer fetched manually
const resp = await fetch('orders.parquet');
await engine.registerParquet('orders', await resp.arrayBuffer());

const mdl = {/* … MDL manifest … */};

// Source must be empty string when using inline registration
await engine.loadMDL(mdl, { source: '' });

In this mode, the engine stores ArrayBuffer instances internally and processes queries against these in-memory buffers. This eliminates network dependencies during query execution but consume memory proportional to the total dataset size.

How URL Mode Works in wren-core-wasm

URL mode leverages DataFusion's ListingTable to access remote Parquet files via HTTP without pre-loading the entire dataset. As implemented in core/wren-core-wasm/src/lib.rs, the engine reads only the specific byte ranges required for each query using HTTP Range requests.

The implementation documented in core/wren-core-wasm/README.md (lines 74-80) shows that URL mode requires only the base URL in the profile.source field:

import { WrenEngine } from '@wrenai/wren-core-wasm';

const engine = await WrenEngine.init();

const mdl = {/* … MDL manifest … */};

// Provide base URL; no explicit registration needed
await engine.loadMDL(mdl, { source: 'https://cdn.example.com/data/' });

const rows = await engine.query(
  `SELECT customer, SUM(amount) AS total
   FROM "Orders"
   GROUP BY customer`
);

DataFusion first requests the file footer to read metadata, then fetches only the specific row groups needed to satisfy the query. This requires the HTTP server to return 206 Partial Content responses and support CORS headers.

Key Differences Between Inline and URL Mode

Data Loading Mechanism

Inline mode transfers the entire dataset during initialization. The application must fetch files manually and pass ArrayBuffer objects to registerParquet, registerCsv, or registerJson. All subsequent queries operate on these retained buffers.

URL mode defers data access until query execution. The engine constructs HTTP Range requests dynamically, reading only the Parquet footer first (to determine column statistics), then pulling specific row-group chunks as needed.

Server Requirements

Inline mode imposes no server constraints beyond standard HTTPS hosting. It works with static site hosts, GitHub Pages, or bundled applications that cannot serve custom headers.

URL mode requires servers that support:

  • Range: request headers (essential for partial content delivery)
  • CORS headers for cross-origin access
  • 206 Partial Content HTTP responses

Servers lacking Range support will cause fetches to hang indefinitely, as documented in core/wren-core-wasm/README.md (lines 106-110).

Performance Characteristics

Inline mode offers faster query response times after the initial load, since data resides in memory. However, it requires sufficient RAM to hold the entire working set and incurs upfront download costs. The documentation recommends this approach for datasets under approximately 50 MB.

URL mode scales to larger datasets by streaming only necessary data, but each query incurs network round-trip latency. This approach is optimal when serving multi-gigabyte Parquet files from CDNs or when minimizing initial page load times.

When to Use Inline Mode vs URL Mode

Choose inline mode for:

  • Local development and demos
  • Bundled dashboards where data ships with the application
  • Environments without Range header support
  • Total dataset sizes below 50 MB

Choose URL mode for:

  • Large datasets hosted on CDNs (CloudFront, Cloudflare, etc.)
  • Scenarios requiring on-demand streaming without upfront downloads
  • Production deployments where minimizing bundle size is critical
  • Parquet files optimized with sorted columns and predicate pushdown

Implementation Examples

Inline Mode Implementation

This example demonstrates the complete inline workflow, including mandatory registration before MDL loading:

import { WrenEngine } from '@wrenai/wren-core-wasm';

const engine = await WrenEngine.init();

// Register JSON data
await engine.registerJson('orders', [
  { id: 1, customer: 'Alice', amount: 100 },
  { id: 2, customer: 'Bob',   amount: 200 },
]);

// Or register a Parquet file that you fetched yourself
const resp = await fetch('orders.parquet');
await engine.registerParquet('orders', await resp.arrayBuffer());

const mdl = {/* … MDL manifest … */};

// In inline mode the source is an empty string because tables are pre‑registered
await engine.loadMDL(mdl, { source: '' });

const rows = await engine.query('SELECT * FROM "Orders" LIMIT 5');
console.table(rows);

URL Mode Implementation

This example shows the streamlined URL mode setup, where profile.source points to the data directory:

import { WrenEngine } from '@wrenai/wren-core-wasm';

const engine = await WrenEngine.init();

const mdl = {/* … MDL manifest … */};

// Provide the base URL where the Parquet files live.
// No explicit register calls are needed.
await engine.loadMDL(mdl, { source: 'https://cdn.example.com/data/' });

const rows = await engine.query(
  `SELECT customer, SUM(amount) AS total
   FROM "Orders"
   GROUP BY customer`
);
console.table(rows);

Summary

  • Inline mode requires calling registerParquet, registerCsv, or registerJson before loadMDL, stores data as ArrayBuffer objects in memory, and works best for datasets under 50 MB without special server requirements.
  • URL mode passes a base URL to loadMDL via the source parameter, utilizes DataFusion's ListingTable with HTTP Range requests, and requires servers supporting CORS and 206 Partial Content responses.
  • The choice depends on data size, server capabilities, and whether you prioritize initial load speed (inline) or scalability (URL).

Frequently Asked Questions

Can I use both inline mode and URL mode simultaneously in the same engine instance?

No, the modes are mutually exclusive for a given table. When using inline mode, you must register all tables explicitly with empty source strings before calling loadMDL. In URL mode, the source parameter contains the base URL and the engine ignores any previous register* calls, instead attempting to resolve table names as relative paths against the provided URL.

What happens if my HTTP server does not support Range headers when using URL mode?

Queries will hang or fail because DataFusion cannot read the Parquet file footer or row groups. According to the core/wren-core-wasm/README.md documentation (lines 106-110), URL mode requires servers that return 206 Partial Content responses. Without this support, the WebAssembly engine cannot perform the random-access reads necessary for columnar data processing.

Is there a practical file size limit for inline mode?

While the WebAssembly engine itself imposes no hard limit, the documentation recommends keeping inline datasets under approximately 50 MB. Beyond this threshold, initial fetch times and memory consumption become prohibitive for browser environments. For larger datasets, migrate to URL mode to leverage HTTP Range request streaming.

Does URL mode support CSV and JSON files?

No, URL mode specifically requires Parquet files because DataFusion's ListingTable implementation relies on Parquet's columnar metadata and footer structure to perform efficient Range-based reads. CSV and JSON lack the necessary metadata headers that enable partial file access, so these formats are only available through inline mode using registerCsv or registerJson.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →