Wado

WEP: JSON Module Import

Date: 2026-01-18 Status: Superseded by Kiln — Keyed IDL Lowering Notation

JSON compile-time import is no longer a compiler-level feature. The same user-visible syntax (use config from "./config.json" with { ... }) is now provided by a Kiln generator (e.g. core:kiln-json), which lowers JSON to a Wado module via the wado:kiln/generator world. Only the file-extension dispatch and cache logic live in the compiler; parsing, typing, and code emission all move to the generator. The sections below are preserved for historical context.

Context

Modern applications rely heavily on configuration files, test fixtures, and static data. Traditionally, these are either:

  1. Hardcoded in source files (inflexible, requires recompilation)
  2. Loaded at runtime from files (requires filesystem access, slower startup, runtime parsing overhead)

For Wasm/WASI applications, runtime file loading has additional challenges:

Wado's JSON literal compatibility (see WEP: JSON Literal Compatibility) provides a foundation for a better approach: compile-time JSON module imports. By loading JSON files during compilation, Wado can provide zero-cost data loading with full type safety.

Decision

Wado supports importing JSON and JSONC files as compile-time modules using the use statement with explicit type annotation.

Syntax

// JSON import
use config from "./config.json" with { type: "json" };

// JSONC import (JSON with Comments)
use settings from "./settings.jsonc" with { type: "jsonc" };

// Access namespace members
let app_name = config::name;
let version = config::version;

Strict Parsing Behavior

The Wado compiler enforces strict parsing based on the specified file type:

This strict behavior ensures that imported files remain compatible with standard JSON tooling (VSCode, jq, prettier, JSON Schema validators).

Type Annotation Requirement

For security reasons, JSON imports require explicit type annotation:

// ✅ Correct: explicit type annotation
use config from "./config.json" with { type: "json" };

// ❌ Error: missing type annotation
use config from "./config.json";

This requirement prevents accidental execution of malicious code (e.g., a .json file that contains executable Wasm or JavaScript disguised as JSON).

Compile-Time Embedding

JSON data is parsed and embedded into the Wasm binary at compile time:

  1. Compiler reads the JSON file
  2. Parses it according to the specified type (json or jsonc)
  3. Converts JSON types to Wado types:
    • JSON object → TreeMap<String, Value> (or inferred struct type)
    • JSON array → List<T> or tuple [T, U, V] (depending on context)
    • JSON string → String
    • JSON number → i32, f64, etc. (inferred from usage)
    • JSON boolean → bool
    • JSON null → Option::None
  4. Embeds the data as Wasm constants
  5. Exposes it as a namespace module

There is no runtime parsing, no filesystem dependency, and no dynamic type checking.

Future Extension: Schema Validation

In the future, Wado may support JSON Schema validation at compile time:

use config from "./config.json" with {
    type: "json",
    schema: "./config.schema.json"
};

This would enable:

Future Extension: Custom Module Loaders

As Wado evolves, users may be able to define custom module loaders for other formats (TOML, YAML, Protocol Buffers, etc.). The with { type: "..." } syntax provides extensibility for this future capability.

Consequences

Benefits

1. Zero-Cost Abstraction for Data

2. Wasm/WASI Context Advantages

3. Configuration as Code (CaC)

4. Strict Parsing Ensures Ecosystem Compatibility

5. Security

6. Performance Equivalent to Serde at Zero Runtime Cost

Trade-offs

1. Larger Binary Size

2. Recompilation Required for Data Changes

3. No Dynamic Schema

Alternatives Considered

1. Runtime JSON Parsing (Rejected)

2. TOML as Primary Config Format (Rejected)

3. YAML as Primary Config Format (Rejected)

4. JSON5 Support (Rejected)

5. Allow Wado Extensions in .json Files (Rejected)