Platforms & Targets
Compile one program without hiding its host dependencies
VibeLang is designed to target TypeScript, native code, and Wasm. Portability is checked through the same requirement system used for application services.
Target Families
| Target | Intended output | Host examples |
|---|---|---|
| TypeScript | ordinary TypeScript or JavaScript | Node, Bun, Deno, browser, edge |
| Native | near-native code through LLVM | server, CLI, worker |
| Wasm | portable WebAssembly | browser, WASI, sandbox |
The TypeScript target supports the complete TypeScript language. Native and Wasm targets classify features according to whether they can be implemented safely and predictably.
Platform as Capability
Host facilities are not unconditional globals in authored .vibe code:
function refreshCache(): Result<void, HttpError | FileError> {
const clock = Clock.context()
const http = HttpClient.context()
const fs = FileSystem.context()
const data = http.get(cacheUrl(clock.today())).unwrap()
fs.writeBytes(cachePath, data.body).unwrap()
}The compiler records exactly what the function needs from its inherited .context() calls. Requirements propagate through ordinary callers without context parameters, and a deployment layer supplies implementations valid for its target.
process, window, document, ambient filesystem access, and ambient network access are modeled as requirements rather than universally available globals.
Feature Classification
VibeLang classifies TypeScript and JavaScript behavior in three groups:
- Portable — implemented on TypeScript and native targets.
- TypeScript-required — valid, but adds the built-in
TypeScriptrequirement. - Forbidden — unavailable in authored
.vibecode.
For example, any and eval are valid on the TypeScript target but add TypeScript. Type-only imports do not add a runtime requirement.
Native Pins
A native pin is a checked assertion that a function's complete dependency graph can run without the TypeScript requirement:
// Exact modifier spelling is still open.
native function checksum(bytes: Uint8Array): Digest {
return Hash.blake3(bytes)
}If a transitive call, provider, or dynamic feature requires TypeScript, compilation fails with the dependency path that introduced it.
Selecting a Target
Use comptime.target when the implementation differs by output environment:
import { comptime } from "vibelang:comptime"
const implementations = {
node: NodeFileSystem,
bun: BunFileSystem,
deno: DenoFileSystem,
native: NativeFileSystem,
wasm: WasiFileSystem,
}
const FileSystemLive = comptime(implementations[comptime.target])Unselected implementations are not emitted.
Foreign Sources
Zig and Rust source modules import directly, with compiler-generated typed bindings:
import { hashMany } from "./hash.zig" with { type: "zig" }
import { parse } from "./parser.rs" with { type: "rust" }The compiler owns toolchain invocation and caching. The import's types, source maps, selected target, toolchain versions, feature flags, and foreign dependency graph contribute to its cache identity. Whether a source import becomes native code, Wasm, or a TypeScript-runtime bridge is target- and toolchain-driven; the exact selection policy remains open.
The TypeScript target also supports existing Node-API npm packages, including addons built with napi-rs:
import { parse } from '@acme/parser-native'These packages keep their published TypeScript declarations and runtime behavior. Node.js and Bun load their .node binaries through Node-API—Bun uses its napi loader for .node—but that host-specific dependency is not silently portable to native or Wasm targets.
Runtime Model
Native output is expected to use a Go-like compiled runtime with garbage collection. Closures, classes, generics, unions, and async functions are not rejected merely because they need runtime support.
Backend-specific lowering is allowed. The source-level failure, requirement, and control-flow semantics remain consistent.