Small. Fast. Expressive.
Tiny is a lightweight scripting language and stack-based bytecode VM written in Go.
Tiny sits in the "sweet spot" between a quick bash script and a complex Go program. It’s perfect for CLI tools, JSON automation, HTTP services, and native-plugin experiments.
- Dynamically typed with optional static type hints
- Structural interfaces for defining object shapes
- Compiles to bytecode (.tbc) and runs on a custom VM
- Case-sensitive syntax
- In-place bytecode optimizations (fusing common loop and variable operations)
- Built-in Language Server (LSP) for VS Code (supporting syntax warnings, autocomplete, jump-to-definition, and renaming)
- Single-binary packaging (
tiny packbundles your script and the VM into a standalone executable) - Native Go-based standard library, including:
io(console I/O)fs(file system operations)json(high-performance parsing and stringifying)http(built-in client and server)math(math operations and matrix multiplication)desktop(CGO-free mouse, keyboard, and clipboard automation)test(integrated unit testing framework)process,regex,time,net,sync
Tiny has a built-in Language Server (LSP) to provide a modern development workflow. You can install the official VS Code extension for syntax highlighting, autocomplete, and diagnostics. The LSP supports advanced static analysis features such as type narrowing, which refines variable types after conditional checks.
The extension can be downloaded by searching for "Tiny" in the VS Code extension marketplace.
Tiny uses structural typing. Objects are validated against interfaces based on their shape without explicit implementation.
import std "io";
interface Task {
title: string
done: bool
}
fn complete(t: Task) {
io.println(`Completing: ${t.title}`);
}
complete({ title: "Write Documentation", done: false });import std "io";
class Greeter {
field prefix = "Hello";
fn init(p) { this.prefix = p; }
fn greet(name) {
return `${this.prefix}, ${name}!`;
}
}
let g = Greeter("Welcome");
io.println(g.greet("Tiny"));The built-in test module provides a standard way to verify logic.
import std "test";
test.run("math operations", fn() {
test.assert(1 + 1 == 2, "basic addition");
test.equal(10 * 2, 20, "multiplication check");
});import std "io";
import std "time";
let task = spawn fn() {
time.sleep(1000);
return "Result from background!";
};
io.println("Doing other things...");
io.println(await task);You can download the pre-compiled executable for your OS from the Releases Page.
- Move the binary into a folder named
.tinyin your home directory (e.g.,C:\Users\YourName\.tiny\tiny.exeor~/.tiny/tiny). - Add the
.tinyfolder path to your system'sPATHenvironment variable. - Grab the official VS Code extension from the marketplace for LSP support.
If you prefer to build from source, clone the repository and build:
git clone https://github.com/confh/Tiny.git tiny
cd tiny
# On Linux/macOS
./build.sh
# On Windows
.\build.batTiny compiles source files into a custom binary bytecode instruction stream (.tbc) before running them. The VM uses several optimizations to keep things fast:
- Fast Slot-Based Access: Both local and global variables are resolved by the compiler and indexed as flat numeric slots inside call frames and global storage, eliminating expensive string-map lookups during execution.
- Instruction Fusing: The optimizer passes over the bytecode and fuses common sequences (like
OP_LOAD_LOCALfollowed byOP_INCandOP_ASSIGN) into single, optimized opcodes likeOP_INC_LOCAL. - Constant Folding: Static math expressions (like
1 + 2 * 3) are evaluated by the compiler during codegen rather than at runtime. - Go GC Integration: Tiny values are directly backed by Go's concurrent garbage collector, so memory is handled automatically.
Tiny has built-in tools to package and distribute your code:
You can bundle your compiled bytecode and the Tiny interpreter into a single standalone binary using the pack command:
tiny pack src/main.tiny -o mytoolThe embedstr and embedbin keywords allow you to include external assets directly in the compiled bytecode.
embedstr "./config.json" const config
embedbin "./icon.png" const iconBytes
// Assets are bundled into the .tbc or packed executableIf your project uses Native Plugins (DLLs/SOs), tiny dist is the answer. It packs the executable and automatically gathers all linked plugins into a clean dist/ folder.
tiny dist src/main.tiny -o release/appTiny is an open-source project licensed under the MIT License.


