HighX
Platform

Compiler

What gets exposed, what gets generated, and the boundary it enforces.

The compiler reads your exported descriptors from the TypeScript AST, validates what may be exposed, and generates the API surface. It is a static defence-in-depth check — not a sandbox, and not a complete proof about JavaScript.

What gets exposed

Exporting a descriptor is what exposes it. A function you do not export cannot be called from a client, which is how internal helpers stay internal.

A descriptor may declare its own name; otherwise the compiler derives <module>.<export>. Paths are dot-separated camelCase segments and must be unique.

RejectedWhy
A descriptor built by a call the compiler cannot readIts options cannot be validated
Missing args, returns, or handlerThe boundary would be unvalidated
Missing authBeing public must be written down, not forgotten
Two descriptors resolving to one pathThe wire path would be ambiguous
A name that is not a valid wire pathPaths are part of the protocol
A descriptor in a "use client" moduleServer code must not reach a client bundle

Every diagnostic names the module and export that produced it, and any diagnostic fails the build.

What gets generated

Two modules with very different properties.

The client half contains only string literals:

.highx/api.ts
export const api = {
  notes: { list: "notes.list", save: "notes.save" },
} as const;

A browser bundle can address every function without an import path that could pull server code in. That is the bundle separation — enforced by construction, not by a lint rule.

The server half imports the real descriptors and emits its own dispatch, so adding a function needs no wiring and the two halves cannot desynchronize.

It also writes .highx/auth.ts, the whole authorization surface, so a test can assert on it.

Gating the bundle

The boundary check runs as part of the real build, not only in tests:

bun run check:client
server_client_crossing: Client entry reaches server-only module …/.highx/server-api.js
  import chain: …/src/main.tsx -> …/.highx/server-api.js

A module that is server-only by its identifier — node:, cloudflare:, @highx/runtime — is classified without being read, because reporting it as "unreadable" would hide the real violation.

Binding inference

The same analysis works out which platform bindings your code needs, so you never declare them twice. → CLI

On this page