Tooling
TinyFX has one Rust compiler frontend and several ways to use it: the native CLI, a browser compiler/runner package, the language server, the VS Code extension, and the playground.
CLI
The main commands are:
tfx check app.tfx
tfx run app.tfx [--watch] [--trace-passes] [--profile[=json]] [--storage-namespace NAME]
tfx run app.tfx --duration 5s --screenshot frame.png
tfx run app.tfx --duration 3s --screenshot frame.png --viewport-size 1000x600 --screenshot-scale 0.5 --no-stats
tfx build app.tfx [-o app.tfxb]
tfx info app.tfx
tfx fmt std examples [--check]
tfx reference --format markdown -o docs/refs/operations.mdxcheck performs parsing, semantic checking, stage analysis, and native WGSL
validation without opening a window. run compiles source or loads .tfxb,
then executes it through the Rust VM and wgpu runtime. info exposes stable
entry and per-file display metadata for source or compiled artifacts.
--explain-passes is available with check and build. It reports compiler
pass construction in stable source order; --explain-passes=json is the
machine-readable form. run --trace-passes reports native adapter-dependent
selection decisions observed at runtime. Static explanations do not claim that
a candidate actually ran.
Native run --profile prints wall/CPU/GPU frame timings, logical and physical
pass counts, transfer/clear counters, and every named profile scope once per
second and immediately before an automatic or interactive exit. Use
--profile=json for newline-delimited tinyfx.profile/0.1 records. GPU timing
fields remain asynchronous and may describe an older completed frame.
run --duration 5s exits after five seconds of native execution. A bare
--screenshot frame writes frame.png after the first completed frame, or just
before a duration-controlled exit when --duration is present. Schedules can
override that default: frame@2s, frame@1s,2s, or frame@1fps. Multi-frame
captures are numbered before the extension, and each completed capture prints
its path and elapsed time to standard output.
Use --viewport-size WIDTHxHEIGHT for a physical-pixel viewport that stays
independent of display scaling and overrides an env.configureWindow size
request. --no-stats removes both the built-in performance lines and custom
stat() lines from the rendered output, which is useful for clean,
deterministic screenshots.
--screenshot-scale SCALE rescales the PNG after rendering. For example, a
1000x600 viewport with --screenshot-scale 0.5 produces a 500x300 image;
this is useful for thumbnails with a smaller UI while preserving a fixed output
size.
Native persistent storage uses a namespace derived from the canonical entry
path. Pass --storage-namespace NAME to give a packaged or movable application
an explicit stable identity. The namespace selects data under TinyFX's platform
data directory; it does not change asset resolution.
The full command/output list is in the CLI reference.
Compiler outputs
tfx build can produce four complementary forms:
| Output | Purpose |
|---|---|
.tfxb | Versioned VM bytecode plus GPU blueprints for native and browser-WASM execution. |
--emit-wgsl | Inspectable WGSL render and compute modules. |
--emit-typescript | Readable structured ESM/TypeScript CPU lifecycle backed by @tinyfx-lang/runtime. It contains no VM bytecode. |
--emit-webgpu | Compiler-authored physical pass modules, metadata, and embedded WGSL by default; --webgpu-wgsl sidecar emits statically imported WGSL sidecars. |
Generated TypeScript/WebGPU supports the repository's current resource,
render, depth, MRT, and compute shapes. The exact operation-level state,
routing, and conformance evidence are generated rather than summarized here;
consult refs/operations.mdx.
Formatter
The formatter is a token-stream reprinter, not an AST pretty-printer. This is
intentional: comments and significant token adjacency must survive formatting.
It preserves an author's line breaks while normalizing indentation and spaces.
It also materializes omitted line-end statement terminators as ;. For source
that already has explicit terminators, the test suite asserts that formatted
source lexes to the same token stream. All formatted output must still parse;
that matters because >> is represented as adjacent > tokens.
Use tfx fmt for files and cargo fmt for the Rust workspace. tfx fmt
uses two-space indentation by default.
Language server and VS Code
crates/tinyfx-lsp is a stdio LSP server. Each open .tfx document is
analysed as a program with the embedded standard library. It serves
diagnostics, hover, signature help, completion, symbols, formatting, and
go-to-definition. Definitions into the standard library work by materializing
the embedded sources under the operating system temporary directory.
On parse errors, a full checked program is unavailable; completion falls back
to a cached standard-library frontend so basic API help remains useful. The
VS Code extension in editors/vscode uses an explicit configured server first,
then its platform-specific bundled tinyfx-lsp. Repository development
packages without a bundled server fall back to the workspace target/
directory and then PATH.
cargo build --release -p tinyfx-lsp
cargo test -p tinyfx-lsp
pnpm --dir editors/vscode packageBrowser package and playground
packages/tinyfx exposes lazy compiler tooling (check, complete, hover,
definition, compile, and source-to-.tfxb) and run. run validates and
compiles source before dynamically importing the memoized runner artifact, so
invalid source does not download the WebGPU-heavy runner.
apps/playground uses those APIs with Monaco. Its editor is a multi-file
project: the active file is treated as the entry, while sibling tab files can
be imported. Browser-only code such as Monaco, WASM, and canvas setup is
dynamically imported from client effects because the app is server-rendered.
@tinyfx-lang/vite is the supported Vite integration for importing .tfx
files as directly runnable VM modules. It compiles the transitive TinyFX module
graph to embedded .tfxb, tracks source and literal asset dependencies through
Vite, and can generate deterministic ambient declarations for matched entries.
The current plugin target is explicitly "vm"; generated TypeScript/WebGPU is
a separate compiler-output path. See the package README in
packages/tinyfx-vite for setup and the exported module shape.
Validation commands
cargo test --workspace
cargo clippy --workspace
cargo fmt --all -- --check
cargo check -p tinyfx-wasm --target wasm32-unknown-unknown
pnpm --dir apps/playground typesReal GPU render tests self-skip when an adapter is unavailable. A successful Rust build is not a browser proof: Chrome's Tint validator can reject WGSL that native naga accepts. See testing for expected validation by change type.