Documentation menu

Roadmap

Compiler roadmap

Status: Prioritized implementation plan based on the current source tree.

The compiler is a credible v3 foundation, but it is not a complete Handlebars implementation or a finished application compiler. Its strongest properties are one Go semantic model, deterministic server IR, UTF-16 editor mappings, failure-path coverage, persistent process clients, and packaged platform binaries. Its main remaining risk is not code volume; it is contract depth at the seams between Go, TypeScript, Vite, editor tooling, and the runtime.

The current authoring boundary is in the template-language reference. Work below must extend that reference only after executable acceptance tests exist.

P0: contract integrity

This milestone is complete in the current branch:

  • Empty dependency metadata is always [], never null, so Node consumers can safely iterate it.
  • Mapping kinds use one closed vocabulary shared by Go, the compiler client, and typed Handlebars.
  • A shared fixture and a real Go-to-Node protocol test detect cross-language schema drift.
  • Wire requests reject an absent or empty sourceName at the protocol boundary.
  • Type synchronization treats every compiler error, including a missing Props alias, as a transactional failure and preserves last known-good declarations.
  • Frontmatter directive and Props discovery ignores comments and string contents.
  • The language, diagnostic catalog, artifact invariants, wire limits, and pipeline ownership are documented as current behavior.

P1: make typechecking a build guarantee

The compiler emits useful TypeScript probes, but a normal Vite build does not yet require those probes to pass. Some emitted probes prove that a path exists without constraining the runtime value domain expected by escaped text, attributes, if, each, or trusted HTML.

Acceptance criteria:

  • goldar build fails on template type errors without requiring a separate manual tsc command.
  • Escaped expressions accept only runtime-renderable primitives.
  • Triple mustaches require TrustedHtml statically as well as dynamically.
  • each collections are arrays, imported-template props are exact, and bound attributes use the same value domain as the renderer.
  • Diagnostics map back to the smallest source expression and are covered through a packed consumer.

Track the compatibility/version policy alongside #41; tightening a probe may be an author-visible breaking change even when the View-program schema does not change.

P1: replace scanner shortcuts with HTML states

The tolerant scanner is compact and well tested, but it still treats some HTML contexts as generic text. Raw-text elements such as script and textarea, duplicate attributes, custom-element case, and some mismatched closing-tag recovery need explicit policy rather than incidental behavior.

Acceptance criteria:

  • Raw-text and escapable-raw-text elements have fixtures for <, {{, and close-like text.
  • Duplicate attributes and case normalization have documented, deterministic diagnostics.
  • Closing-tag diagnostics select the exact offending name and recovery retains following siblings.
  • Incomplete-buffer tests prove stable source ranges after every token boundary.
  • Fuzz assertions continue to guarantee deterministic output and in-bounds UTF-16 ranges.

P1: use a real frontmatter tokenizer

The current source-preserving mask prevents comment and string contents from activating compiler directives. The directive grammar itself is still regular-expression based and intentionally line-oriented. TypeScript template-string substitutions, semicolon-free multiline imports, and other full-language forms should not be added one regex at a time.

Acceptance criteria:

  • A small tokenizer identifies comments, strings, template literals, identifiers, imports, member calls, and balanced delimiters while preserving byte offsets.
  • The supported directive grammar is explicit and produces source-located diagnostics for near misses instead of silently passing them through.
  • Sanitized frontmatter preserves UTF-16 width and line structure for every removed directive.
  • Tests cover CRLF, astral Unicode, escapes, nested template substitutions, and incomplete edits.

P2: choose interactive View-program semantics

Events, properties, and actions are deliberately rejected today. They should land as one coherent runtime contract, not as syntax that the server renderer ignores. Existing design work is tracked in #29 and #39.

Acceptance criteria:

  • The IR distinguishes attributes, properties, events, and actions with stable identity.
  • Server output defines serialization and progressive-enhancement behavior for every instruction.
  • The browser runtime defines ownership, teardown, event options, update semantics, and trust boundaries without evaluating source strings.
  • Language tooling maps and typechecks the new syntax before the authoring reference exposes it.
  • A no-JavaScript form or Custom Element remains the supported bridge until this milestone ships.

P2: deepen composition and CSS

Named or multiple outlets, route asset manifests, and scoped keyframes should follow demonstrated application needs. Relevant issue tracks include #24 and #27.

Acceptance criteria:

  • Composition defines explicit ownership and rejects ambiguous child placement.
  • Route builds emit exact script/style manifests and server output links the required assets.
  • Scoped keyframe names and animation declarations are rewritten consistently and source errors map to the original CSS.
  • Imported templates preserve style and watch invalidation order across development and production.

P3: operational hardening

The compiler process currently provides a simple request/response lifecycle. Before claiming a stable compiler service, decide and test cancellation, restart, resource ceilings, and compatibility windows. Packaging work should remain aligned with #14 and #15 rather than creating a second distribution path.

Acceptance criteria:

  • Protocol and artifact compatibility have a written support window and upgrade path.
  • The Node owner can distinguish compile failure, protocol failure, crash, timeout, and disposal.
  • Large-input limits are configurable or justified, with package-level failure tests.
  • Benchmarks establish budgets for cold start, steady-state compile latency, allocations, and project synchronization.
  • Released binaries are verified through packed installations on every supported platform.

Non-goals

The compiler should not absorb routing, data fetching, persistence, or browser lifecycle ownership. It should describe template meaning and capabilities precisely enough that those systems can make their own decisions. General Handlebars compatibility is also not a goal unless a specific syntax fits Goldar’s typed, server-first contract and has runtime and editor semantics.