W WRNexusJS
Core · Package reference

@wrnexus/compiler

Parser and code generators for the .wrn language.

v0.8.7Private registryCore

Install the package

After WorkRoot approves private registry access, install the release-aligned package:

bun add @wrnexus/compiler@0.8.7

Request preview access. Never put registry tokens in source control.

Partial-static rendering

Pages can select render = "partial-static" and divide their view with <Static> and <Dynamic> boundaries. The compiler emits a build-only shell renderer that never evaluates dynamic-boundary children. wrnexus build expands static component mounts into dist/partial-shells.json, records byte/region evidence in build-report.json, and embeds the shell in the production route manifest. At request time the production runtime retains request-aware layouts, locale/theme metadata and security nonces while streaming dynamic regions into stable placeholders.

Compiler for the .wrn language — tokenizes, parses, and lowers .wrn page and component files to TypeScript.

Part of the WRNexusJS framework — an SSR-first, Bun-native full-stack web framework.

Production adapters use analyzeRuntimeImports before bundling. Edge, worker, service-worker, and browser targets reject Node filesystem, TCP, and process modules with WRN-RUNTIME-CAPABILITY. Package manifests can declare supported wrnexus.runtimes and required wrnexus.requires capabilities; discovery fails when the selected deployment cannot satisfy them.

Server actions

action createUser using CreateUserSchema {
  const user = await users.create(input)
  invalidate("users")
  return user
}

view {
  <form @submit="createUser">...</form>
}

The compiler produces a schema-aware server registry, a fully inferred action client, and progressively enhanced form metadata. The shared runtime performs validation, authentication/permission checks, CSRF verification, serialization, invalidation reporting, and browser lifecycle events.

Overview

@wrnexus/compiler turns .wrn source into TypeScript that targets the framework's runtime primitives. A .wrn file declares either a page (a route) or a component (a reusable, prop-driven fragment) with blocks for state, view (plain HTML), seo, style, functions, api, ssr/client data bindings, and realtime websocket handlers. The pipeline is source → Lexer → parse() → PageAst → generate() → TypeScript. It is a build/server-side library — the WRNexusJS dev loader calls it to compile .wrn files on the fly, surfacing ParseError as a readable error page.

Static ES module imports may appear before the root declaration. Imported values are available to server-rendered expressions, including component props:

import { appUrl } from "@wrnexus/helpers";

layout PublicLayout {
  view {
    <PublicHeader signInHref="{appUrl('sso', '/sign-in')}" />
  }
}
bun add @wrnexus/compiler
Private package — the machine must be authenticated to the wrnexus npm org
(a read token in ~/.npmrc). Requires Bun (Node is not supported).

API

All exports come from the package root (@wrnexus/compiler).

compileWireFile(source: string): string

Compile .wrn source to a TypeScript module string. Throws ParseError on invalid input. The output is prefixed with a // compiled from .wrn comment.

compile(source: string): CompileResult

Richer entry point that returns the generated code, the AST, and any diagnostics.

interface CompileResult {
  code: string;
  ast: PageAst;
  diagnostics: string[];
}

On a ParseError it pushes the message into diagnostics and re-throws.

parse(source: string): PageAst

Run the lexer + recursive-descent parser and return the AST. Throws ParseError (lexer LexErrors are caught and rethrown as ParseError).

generate(ast: PageAst): string

Lower a PageAst to TypeScript. page ASTs become a default-export page component (plus meta, optional layout, __wrnexusApi/method handlers, websocket, and SSR/CSR data bindings); component ASTs become a module exporting render(props) and __wrnexusComponent.

Lexer

On-demand lexer for .wrn. Yields structural tokens and exposes raw-span readers for the parser.

class Lexer {
  pos: number;
  constructor(src: string);
  next(): Token; // consume next structural token
  peek(): Token; // look ahead without consuming
  readPath(): string; // route path, e.g. /users/[id]
  readToLineEnd(): string; // rest of line (state/prop initializers)
  readBalancedBraces(): string; // inner text of a { ... } block, string-aware
}

Token is { type: TokenType; value: string; pos: number }, where TokenType is one of ident, string, lbrace, rbrace, lparen, rparen, at, eq, comma, eof.

Errors

ClassThrown byMeaning
ParseErrorparse, compile, compileWireFile, generateInvalid .wrn grammar or (rewrapped) lex failure.
LexErrorLexerUnexpected character / unterminated string / unbalanced braces.

AST types

Exported type-only symbols describing the parsed tree:

TypeDescription
PageAstRoot node including top-level imports, kind, name, types, typed props, typed states, view, styles, functions, data APIs, lifecycle, and routes.
ViewNode{ type: "text"; value } or { type: "element"; tag; attrs; children }.
Attr{ name; value; event; boolean? }event marks @event bindings.
StateDecl{ name; valueType?; expr } — a typed state x: Type = <expr> declaration.
PropDecl{ name; valueType?; required; default } — a typed prop declaration.
SeoBlockRecord<string, string> from the seo { ... } block.
ApiBlock{ method; path; body } — a top-level api METHOD /path { ... }.
DataApiBlock{ mode; name; method; path; body } — an api inside an ssr/client block.
DataMode`"ssr" \"client"`.
ModeFunctionsBlock{ mode; body } — a functions { ... } inside an ssr/client block.
RealtimeBlock{ name; handlers } — a realtime <name> { on evt(args) { ... } } block.

Usage

Compile a page:

import { compileWireFile } from "@wrnexus/compiler";

const ts = compileWireFile(`
page Home {
  state count = 0
  seo { title = "Home" description = "Welcome" }
  view {
    <button @click="count++">Clicked {count} times</button>
  }
}
`);
// ts is a TypeScript module: exports `meta`, and a default page component
// returning an HTML string, wrapped in a data-scope for the reactive runtime.

Inspect the AST and diagnostics:

import { compile, ParseError } from "@wrnexus/compiler";

try {
  const { code, ast, diagnostics } = compile(source);
  console.log(ast.kind, ast.name, ast.states.length);
} catch (err) {
  if (err instanceof ParseError) console.error(err.message);
}

Drive the parse/codegen stages directly:

import { parse, generate } from "@wrnexus/compiler";

const ast = parse(componentSource); // ast.kind === "component"
const module = generate(ast); // exports render(props) + __wrnexusComponent

Use the lexer standalone:

import { Lexer } from "@wrnexus/compiler";

const lx = new Lexer("page Home {");
lx.next(); // { type: "ident", value: "page", pos: 0 }
lx.next(); // { type: "ident", value: "Home", pos: 5 }
lx.next(); // { type: "lbrace", value: "{", pos: 10 }

The .wrn language (as parsed)

A file opens with page <Name> or component <Name> followed by a { ... } body containing zero or more members:

  • layout = "<name>" — selects app/layouts/<name>.wrn (pages only).
  • types { <TypeScript declarations> } — reusable interfaces and aliases for the current file.
  • props { name: Type = <default> ... } — typed component props. Omit = <default> to make a prop required. Legacy inferred props remain supported.
  • @event name = function inside props — declares a public component event. Emit it from component behavior with name(detail) or $emit("name", detail), and consume it with <Component @name="handler(event)" />.
  • state <ident>: Type = <expr> — typed reactive state seeded from a raw JS expression, including native array and object literals. The annotation is optional for backward compatibility.
  • view { <html> } — plain HTML with {expr} interpolation in text and attributes, JSX-style component props such as items={items}, items={[...]}, and options={{...}}, hyphenated attributes, boolean attributes, @event="..." client bindings, and <!-- comments -->. Structured component props are serialized safely for SSR; expressions that reference state retain their initial value and update reactively in the browser.
  • Client functions automatically commit state changed by setTimeout callbacks. For other deferred callbacks (observers, third-party APIs, or detached promise callbacks), call the injected commit() function after changing local state; returning/awaiting a promise also commits through the normal function boundary.
  • seo { key = "value" ... } — metadata merged into the generated meta.
  • style { <raw css> } — inlined page/component stylesheet (repeatable).
  • functions { <TypeScript> } — helpers with typed parameters and return values. Types remain in server output and are safely erased from browser behavior code.
  • api <METHOD> <path> { <raw js> } — route handler, lowered to a METHOD export (repeatable).
  • ssr { ... } / client { ... } — data blocks holding api <name> <METHOD> <path> { ... } bindings and their own functions { ... }.
  • realtime <name> { on <evt>(<args>) { <raw js> } ... } — websocket handlers, lowered to a websocket export.

view markup is parsed by a lenient dedicated HTML parser (parseHtmlView); HTML void elements (<br>, <img>, …) take no closing tag. Line comments (//) are skipped by the lexer.

Requirements / Notes

  • Pure TypeScript with no runtime dependencies; runs under Bun as part of the WRNexusJS toolchain (Node is not supported).
  • Generated modules target WRNexusJS runtime primitives (data-scope, data-text, data-on-*, data-for, data-component, __wrnexus*/__wire* helpers) — consume the output within a WRNexusJS app, e.g. via @wrnexus/core's dev loader.

Complete TypeScript API

Generated from the exact installed package declarations.

import { PageAst as PageAst$1, StructuredImportDecl, WrnDiagnostic } from '@wrnexus/syntax';
export { ActionBlock, ApiBlock, Attr, ComputedDecl, DataApiBlock, DataMode, EffectBlock, EventDecl, FormatWrnOptions, LexError, Lexer, LoadBlock, ModeFunctionsBlock, OutputDecl, PageAst, ParseError, PropDecl, RealtimeBlock, RuntimeFunctionDecl, SeoBlock, StateDecl, StateRuntime, StoreKind, StructuredImportDecl, ViewNode, WrnDiagnostic, assertValidAst, diagnose, diagnosticFromError, eraseFunctionTypes, formatDiagnostic, formatWrn, inferredRuntimeType, parse, runtimeTypeOf } from '@wrnexus/syntax';
import { PageAst } from '@wrnexus/syntax/parser';

/**
 * Code generation: lower a `.wrn` AST to TypeScript that targets the framework's
 * existing primitives.
 *
 *   state              -> a `data-scope` declaration consumed by the runtime
 *   view               -> an HTML string returned by a page component
 *   @event="..."       -> data-on-<event>="..."
 *   "...{expr}..."     -> text kept verbatim ({expr} is mustache for runtime)
 *   api="<name>"       -> SSR/client data binding declared in a mode block
 *   ssrGet/ssrText     -> legacy server-side API fetch + render
 *   csrGet/csrText     -> legacy browser-side API fetch + render
 *   style              -> tagged local stylesheet metadata promoted by SSR
 *   functions          -> server-only helpers for API/realtime code
 *   api M /p {b}       -> export const M = async (ctx) => { b }
 *   realtime {..}      -> export const websocket = { evt(ws, ...args) { b } }
 */

declare function generate(ast: PageAst): string;

interface ComponentContractMetadata {
    name: string;
    kind: PageAst$1["kind"];
    props: Array<{
        name: string;
        type: string;
        required: boolean;
        default?: string;
        options?: string[];
    }>;
    outputs: Array<{
        name: string;
        payloadName?: string;
        payloadType?: string;
    }>;
    functions: Array<{
        name: string;
        runtime: string;
        async: boolean;
        parameters: Array<{
            name: string;
            type: string;
            optional: boolean;
        }>;
        returnType: string;
    }>;
    states: Array<{
        name: string;
        runtime: string;
        type: string;
        initializer: string;
    }>;
    computed: Array<{
        name: string;
        type: string;
        expression: string;
    }>;
    imports: Array<{
        source: string;
        typeOnly: boolean;
        defaultImport?: string;
        namedImports: string[];
    }>;
}
declare function createComponentContract(ast: PageAst$1): ComponentContractMetadata;

interface RpcManifestEntry {
    id: string;
    component: string;
    function: string;
    parameters: Array<{
        name: string;
        type: string;
        optional: boolean;
    }>;
    returnType: string;
}
declare function rpcManifest(ast: PageAst$1): RpcManifestEntry[];
declare function generateServerFunctionsModule(ast: PageAst$1): string;

interface CompileTargets {
    server: string;
    browser: string;
    declarations: string;
    contract: ReturnType<typeof createComponentContract>;
    rpc: ReturnType<typeof rpcManifest>;
}
declare function generateTargets(ast: PageAst$1): CompileTargets;

declare function generateBrowserModule(ast: PageAst$1): string;

declare function generateDeclarations(ast: PageAst$1): string;

declare function generateStoreModule(ast: PageAst$1): string;
/** Standalone browser artifact for an imported `.wrn` store. */
declare function generateStoreBrowserModule(ast: PageAst$1): string;

type ImportMode = "legacy" | "compatible" | "explicit";
interface ImportResolverOptions {
    appRoot: string;
    mode?: ImportMode;
    aliases?: Record<string, string>;
}
interface ResolvedImport {
    declaration: StructuredImportDecl;
    resolved?: string;
    diagnostic?: {
        code: string;
        message: string;
        severity: "error" | "warning";
    };
}
declare function resolveWrnImport(declaration: StructuredImportDecl, importer: string, options: ImportResolverOptions): ResolvedImport;
declare function resolveWrnImports(declarations: StructuredImportDecl[], importer: string, options: ImportResolverOptions): ResolvedImport[];

interface WrnSourceMapEntry {
    generatedLine: number;
    sourceLine: number;
    sourceColumn: number;
    kind: string;
}
interface WrnSourceMap {
    version: 1;
    source: string;
    generated: string;
    mappings: WrnSourceMapEntry[];
}
declare function createWrnSourceMap(source: string, generated: string): WrnSourceMap;

type RouteExecutionKind = "static" | "static-interactive" | "request-ssr" | "authenticated-ssr" | "streaming-ssr" | "dynamic";
interface RuntimeRequirements {
    kind: RouteExecutionKind;
    canPrerender: boolean;
    needsClientRuntime: boolean;
    needsServerRuntime: boolean;
    hydrationStrategy: string | null;
    reasons: string[];
    optimization: OptimizationReport;
    cachePolicy: Record<string, string>;
    requiredPermission: string | null;
}
interface OptimizationReport {
    staticNodes: number;
    reactiveRegions: number;
    eliminatedBranches: number;
    unusedState: string[];
    unusedHandlers: string[];
    constantProps: string[];
    unusedLocalCssClasses: string[];
    batchableStateUpdates: number;
    memoizableComponents: string[];
    preloadDependencies: string[];
    serverOnlyModules: string[];
}
/** Safe compile-time folding for literal conditional branches. */
declare function optimizeAst(ast: PageAst$1): {
    ast: PageAst$1;
    eliminatedBranches: number;
};
declare function analyzeOptimizations(ast: PageAst$1): OptimizationReport;
declare function analyzeRuntimeRequirements(ast: PageAst$1): RuntimeRequirements;

type DeploymentRuntime = "bun" | "node" | "edge" | "worker" | "service-worker" | "browser";
type RuntimeCapability = "filesystem" | "tcp" | "process" | "websocket" | "crypto" | "streams" | "background-tasks";
interface RuntimeCapabilityDiagnostic {
    code: "WRN-RUNTIME-CAPABILITY";
    runtime: DeploymentRuntime;
    module: string;
    capability: RuntimeCapability;
    message: string;
}
declare function runtimeCapabilities(runtime: DeploymentRuntime): ReadonlySet<RuntimeCapability>;
declare function analyzeRuntimeImports(source: string, runtime: DeploymentRuntime): RuntimeCapabilityDiagnostic[];

declare class NativeCompileError extends Error {
    constructor(message: string);
}
/** Compile a parsed `.wrn` page to an Expo Router React Native screen. */
declare function generateNative(ast: PageAst): string;

interface CompilationCacheEntry extends CompileResult {
    key: string;
    file: string;
    sourceHash: string;
    createdAt: number;
}
interface CompilationCacheOptions {
    maxEntries?: number;
    now?: () => number;
}
interface CompilationCache {
    compile(source: string, file?: string, salt?: string): CompilationCacheEntry;
    get(key: string): CompilationCacheEntry | undefined;
    invalidate(file?: string): number;
    clear(): void;
    size(): number;
    stats(): {
        hits: number;
        misses: number;
        entries: number;
    };
}
declare function compilationKey(source: string, file?: string, salt?: string): string;
declare function createCompilationCache(options?: CompilationCacheOptions): CompilationCache;
declare class DependencyGraph {
    #private;
    set(file: string, dependencies: Iterable<string>): void;
    remove(file: string): void;
    dependencies(file: string): string[];
    dependents(file: string): string[];
    affected(file: string): string[];
}

/**
 * @wrnexus/compiler — the `.wrn` language compiler.
 *
 * Parsing and language diagnostics are provided by the canonical
 * `@wrnexus/syntax` package. This package owns platform-specific codegen.
 */

interface CompileResult {
    code: string;
    ast: PageAst$1;
    /** Backward-compatible plain diagnostic messages. */
    diagnostics: string[];
    /** Structured diagnostics for editors, CI, and the DevToolbar. */
    richDiagnostics: WrnDiagnostic[];
}
/** Compile `.wrn` source into an Expo Router React Native screen. */
declare function compileNativeWireFile(source: string): string;
/**
 * Compile `.wrn` source into TypeScript source. Errors include a stable code,
 * source location, code frame, and actionable hint whenever available.
 */
declare function compileWireFile(source: string, filePath?: string): string;
/** Richer entry point returning the AST and structured diagnostics. */
declare function compile(source: string, filePath?: string): CompileResult;

export { type CompilationCache, type CompilationCacheEntry, type CompilationCacheOptions, type CompileResult, DependencyGraph, type DeploymentRuntime, NativeCompileError, type OptimizationReport, type RouteExecutionKind, type RuntimeCapability, type RuntimeCapabilityDiagnostic, type RuntimeRequirements, analyzeOptimizations, analyzeRuntimeImports, analyzeRuntimeRequirements, compilationKey, compile, compileNativeWireFile, compileWireFile, createCompilationCache, createComponentContract, createWrnSourceMap, generate, generateBrowserModule, generateDeclarations, generateNative, generateServerFunctionsModule, generateStoreBrowserModule, generateStoreModule, generateTargets, optimizeAst, resolveWrnImport, resolveWrnImports, rpcManifest, runtimeCapabilities };

Examples

Copy-ready examples from the installed package documentation.

Compile a page

import { compileWireFile } from "@wrnexus/compiler";

const ts = compileWireFile(`
page Home {
  state count = 0
  seo { title = "Home" description = "Welcome" }
  view {
    <button @click="count++">Clicked {count} times</button>
  }
}
`);
// ts is a TypeScript module: exports `meta`, and a default page component
// returning an HTML string, wrapped in a data-scope for the reactive runtime.

Inspect the AST and diagnostics

import { compile, ParseError } from "@wrnexus/compiler";

try {
  const { code, ast, diagnostics } = compile(source);
  console.log(ast.kind, ast.name, ast.states.length);
} catch (err) {
  if (err instanceof ParseError) console.error(err.message);
}

Drive the parse/codegen stages directly

import { parse, generate } from "@wrnexus/compiler";

const ast = parse(componentSource); // ast.kind === "component"
const module = generate(ast); // exports render(props) + __wrnexusComponent

Use the lexer standalone

import { Lexer } from "@wrnexus/compiler";

const lx = new Lexer("page Home {");
lx.next(); // { type: "ident", value: "page", pos: 0 }
lx.next(); // { type: "ident", value: "Home", pos: 5 }
lx.next(); // { type: "lbrace", value: "{", pos: 10 }