Skip to content

Instantly share code, notes, and snippets.

@simbo1905
Created September 28, 2026 15:34
Show Gist options
  • Select an option

  • Save simbo1905/5be015475abd1a1611c0e996218ce4e7 to your computer and use it in GitHub Desktop.

Select an option

Save simbo1905/5be015475abd1a1611c0e996218ce4e7 to your computer and use it in GitHub Desktop.
vanilla-pod-js — framework-free typed browser JS: JTD schemas → generated validate() validators → validate-then-freeze → typed fetchers → light-DOM web components. JSDoc + tsc --noEmit, NO transpiler

vanilla-pod-js — framework-free typed browser JavaScript, no transpiler

One discipline for writing 2025-baseline browser JavaScript that is actually type-checked, validated at the perimeter, and shipped as plain JS.

The problem it kills

TypeScript sells you compile-time checking and then makes you transpile, ship .d.ts, and fight a build system — all to end up with types that vanish at runtime, exactly where untrusted JSON arrives. The usual alternatives (Zod, io-ts) add a runtime dependency to reinvent what a JSON type system already does.

The system

  1. JTD schemas (.jtd.json) are the types. RFC 8927 is a standard, compact, language-agnostic JSON type system. One schema, many consumers: JS validators today, Rust/WASM or Java or Lua checkers tomorrow.
  2. Generated validators, not hand-written guards. jtd-codegen emits a validate(instance) → ValidationError[] per schema — zero imports, only the checks the schema requires, collecting all errors in one pass (instancePath/schemaPath JSON Pointers).
  3. Barrel re-exports. Every generated module exports validate, so the barrel renames per stem (validateTrayUpdate, validateCaseWorkspaces). Import from the barrel, never alias two validates into one scope.
  4. Validate-then-freeze perimeter. Parse → validate → deep-freeze → hand the frozen object to the app. Everything downstream is Readonly by construction.
  5. Typed fetchers over NDJSON row streams. Fail-closed: a row that fails validation stops the stream, not a silent any leak.
  6. Light-DOM Web Components. No framework, no shadow-DOM style isolation tax, no build step.
  7. JSDoc + tsc --noEmit. Full type checking of handwritten code with zero transpilation, zero .d.ts, zero emitted artefacts. The generated validators carry // @ts-nocheck; everything you write stays checked.

Why "no transpiler" is the point

JTD types travel across languages: the same schema drives a Rust/WASM checker, a Java codegen (json-java21-jtd-codegen), or a Lua runtime validator. The types are not a TS artifact — they are data. Exhaustive switches over a JTD enum + properties give you sealed-trait ergonomics in any language that has a switch. The skill is the JS expression of that one idea.

Proven in production

Shipped end-to-end in the LSE AI Leadership course site (549-page corpus): AOT-generated validators guarding the chat tool-call surface, JTD-validated Zoom session ingestion, search over a Tantivy WASM index — tsc --noEmit clean, browser QA suite green, no framework anywhere.

History

This consolidates a family of older gists (vanilla-js-jsdoc, typed fetchers, teal exhaustive-switch experiments, barrel validators) that were reduced via a linear margin-note pass into one skill. Those gists now point here.

The skill repo is private; the catalogue and the JTD tooling repo are public. Ask simbo1905 for access.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment