Getting started
TinyFX programs use the .tfx extension. The native CLI compiles source and
opens a winit window; the browser package exposes the same compiler and a
WebGPU runner for a canvas.
Native CLI
Build the debug CLI from the repository root:
cargo build -p tinyfx-cli
# Type-check without opening a window.
./target/debug/tfx check examples/fundamentals/cube/main.cube.tfx
# Run a program. --watch recompiles source changes.
./target/debug/tfx run examples/fundamentals/cube/main.cube.tfx --watch
# Format source, or make formatting part of CI.
./target/debug/tfx fmt std examples
./target/debug/tfx fmt std examples --checktfx run accepts source or a compiled .tfxb program. Asset paths in a
native program are resolved relative to that entry file, rather than the shell
working directory. With .tfxb --watch, replacing the artifact reloads its
bytecode directly; source watch mode instead recompiles the entry and imports.
First program
Create hello.tfx:
UV gradient
A small example embedded directly in this guide.fn loop() {
draw(shader {
frag {
out.color = (in.uv.x, in.uv.y, 0.7, 1.0);
}
});
}
Then run it:
./target/debug/tfx run hello.tfxsetup() is optional and runs once before the first frame. loop() is also
optional: a program that draws in setup or global initialization can make a
static image. Read runtime lifecycle before
building stateful applications.
Inspecting compiler output
# Write WGSL modules for shaders and compute kernels.
./target/debug/tfx build hello.tfx --emit-wgsl out/wgsl
# Write a versioned bytecode program for the Rust VM.
./target/debug/tfx build hello.tfx -o hello.tfxb
# Write readable generated TypeScript/ESM CPU code.
./target/debug/tfx build hello.tfx --emit-typescript out/hello.ts
# Write compiler-authored physical WebGPU pass modules.
./target/debug/tfx build hello.tfx --emit-webgpu out/webgpu
# Explain static lowering decisions without acquiring a GPU.
./target/debug/tfx check hello.tfx --explain-passes
./target/debug/tfx build hello.tfx --explain-passes=jsonThe emitted TypeScript is a separate execution target, not a decompilation of
VM bytecode. It depends on @tinyfx-lang/runtime; see
compilation targets and
artifact reference.
Browser playground
The workspace uses pnpm:
pnpm install
pnpm --filter tinyfx build:wasm
pnpm --dir apps/playground devThe browser build is split deliberately. The compiler/editor artifact provides
checking and editor features; the runner artifact is dynamically loaded only
after valid source has compiled to .tfxb. The playground's development
command builds missing artifacts as needed.
For an embedding, the tinyfx package accepts source, optional imported
files, assets, and a canvas. It owns canvas backing-store sizing, so CSS should
size the canvas and application code should not set canvas.width or
canvas.height while it is running:
import { run } from "tinyfx";
await run(canvas, source, {
imports: { "lib/palette.tfx": paletteSource },
assets: { "assets/photo.png": photoBytes },
});See assets in browser embeddings for the resolver contract.
For an application build, install the facade directly or add the Vite plugin
when .tfx files should be importable modules:
npm install tinyfx
npm install tinyfx @tinyfx-lang/viteGenerated TypeScript/ESM consumers install @tinyfx-lang/runtime instead of the
WASM facade. All three packages share the 0.1.x alpha release line, while
generated-core/platform API 1.0, physical pass blueprint 1.0, and .tfxb
format v1 remain independently versioned contracts.
Where to go next
The shortest route into real work is language, then
GPU programming. The examples directory is intentionally useful
documentation too: feedback, fluid, hybrid_depth, buffers,
volumetric_clouds, and webcam_video exercise distinct runtime paths.