Compiler Overview
The Newt compiler transforms .newt source files into rendered UIs. It uses a linear pipeline with five stages, all coordinated by a single compile() function.
Pipeline
1. Lexer
The lexer reads the raw source text and produces a stream of tokens. It recognizes:
- Numbers:
16,3.14 - Strings:
"Hello, world!" - Colors:
#2563eb,#f9fafb - Keywords:
screen,component,state,let,theme,use,import,if,else,for,in,range,true,false - Element names:
row,column,text,button,card, and all other built-in elements - Operators and punctuation:
(,),{,},:,,,+,-,*,/,==,!=,<,>,<=,>=,&&,|| - Identifiers: variable names, component names, parameter names
- Comments: everything after
//until the end of the line is discarded
2. Parser
A recursive descent parser consumes the token stream and produces an Abstract Syntax Tree (AST). The AST root is a Program node containing a list of items:
LetDecl-- variable declarationsStateDecl-- state declarationsComponentDef-- component definitionsScreenDef-- screen definitionsThemeDef-- theme definitionsImportDecl-- import statementsUseTheme-- theme activation
Each element in the tree carries its name, props (key-value pairs), and children (nested elements or control flow nodes).
3. EvalContext
The evaluation context processes the AST in order:
- Registers
letvariables and their values - Registers
statevariables with their initial values - Records component definitions for later expansion
- Resolves
importstatements by loading and parsing the referenced files - Applies
use themeby merging theme variables into the current scope
When a screen is rendered, the EvalContext expands component calls, evaluates expressions, and resolves string interpolation.
4. Layout Engine
The layout engine takes the evaluated element tree and computes a spatial layout. Every element gets a Rect with four fields:
x-- horizontal position in pixelsy-- vertical position in pixelsw-- width in pixelsh-- height in pixels
The engine respects all layout props (padding, gap, grow, shrink, align, justify, width, height, constraints) and uses a flex-based algorithm for rows and columns, and a grid algorithm for grid elements.
The default viewport is 960 x 640 pixels.
5. Render
The final stage produces output in one of two forms:
- Canvas: a wgpu-based window that draws the UI directly on the GPU. Used by the
newter-compilerrun command and the Canvas IDE. - HTML export: a self-contained HTML file where each element becomes a positioned
<div>with inline styles. Used by thebuild --htmlcommand.
The compile() function
All consumers of the compiler -- the CLI runner, the serve command, the build command, and the LSP server -- use the same compile() entry point. This function takes source text and returns the fully laid-out element tree, ensuring consistent behavior across all output modes.
Error handling
The compiler reports errors at each stage:
- Lexer errors: invalid tokens, malformed hex colors, unterminated strings
- Parser errors: unexpected tokens, missing braces, invalid syntax
- Eval errors: undefined variables, unknown components, circular imports
- Layout errors: constraint conflicts, invalid grid templates
Errors include the source location (line and column) so they can be displayed in the editor via the LSP server.
Next steps
- CLI Reference — all commands and flags for the Newt compiler.
- HTML Export — how Newt compiles to static and reactive HTML.
- Canvas IDE — live-reload browser preview with hot module replacement.