A modern programming language for systems, apps, and games. Combines the speed of Zig, the safety of Rust, and the joy of TypeScript.
Status: Home is under active development. The lexer, parser, type inference, and tree-walking interpreter are usable today; native codegen, tooling, the TypeScript frontend, and the Bun-compatible runtime are still maturing. See the parity status section below for percentage-based numbers across every area, with per-feature drill-down pages in
docs/PARITY-TYPESCRIPT.md,docs/PARITY-NODE.md,docs/PARITY-BUN.md, and the widerdocs/CAPABILITY_MATRIX.md.
For release notes see CHANGELOG.md.
The whole status, percentage-based. Every number is a byte-for-byte, file-count, or row-count measurement against an external baseline — not an aspirational target. Each row cites the package, harness, or upstream source that produces it.
Refreshed 2026-07-13. Coarse-mode TS corpus and per-slice exact mode are regression-gated on every PR; Bun port % is file-count progress over integrated Home ports, while raw source presence is reported separately now that the full Bun source backlog has been staged. TS diagnostic-code coverage (1,620 / 2,079 emitted) tracks the catalog- only → emitted ratchet; each
feat(ts-parity): implement TSxxxxcommit moves this row by 1. Note: faithful "100% parity" is the reachable subset — the codes the reference compiler (typescript-go) actually emits — and that subset is now effectively complete: 0 reachable parity targets remain. The ~455 still- unemitted codes are dead in the reference (obsolete/superseded wording it never produces), plus 4 blocked/subsystem-gated references; seedocs/TS_DIAGNOSTIC_REACHABILITY.md.
Detailed per-feature breakdowns (the README is the at-a-glance view; these are the drill-down pages — modeled after Bun's Node.js compatibility doc):
docs/PARITY-TYPESCRIPT.md— every TypeScript feature with 🟢 / 🟡 / 🔴 statusdocs/PARITY-NODE.md— everynode:*module with 🟢 / 🟡 / 🔴 / ❌ statusdocs/PARITY-BUN.md— every Bun API + phase-by-phase port statusdocs/PARITY-BUN-COMPAT.md—packages/compat/shim symbol-by-symbol statusdocs/CAPABILITY_MATRIX.md— full language / codegen / tooling / stdlib matrixdocs/TS_PARITY_PLAN.md— parity plan + dated journal entriesdocs/CONFORMANCE_CATEGORIES.md— per-category TS conformance breakdownpackages/runtime/PORT_AUDIT_2026-05-20.md— Bun runtime port audit; live counts come fromscripts/measure-parity.sh --values
| Area | Coverage | Source |
|---|---|---|
| TypeScript — coarse corpus | 5,907 / 5,907 — 100% | HOME_TS_CONFORMANCE_FULL=1 against upstream conformance corpus |
| TypeScript — exact (byte-for-byte) | 4,871 / 5,907 — ~82.5% | HOME_TS_CONFORMANCE_FULL=1 HOME_TS_CONFORMANCE_EXACT=1; 1,036 exact cases remain |
| TypeScript — baseline-aware (19 folders) | 586 / 586 — 100% | per-fixture .errors.txt byte comparison |
| TypeScript — named-category survey | 86 / 86 — 100% | assignmentCompatibility + comparable + inOperator + stringLiteral |
| TypeScript — diagnostic codes emitted | 1,620 / 2,079 — ~77.9% | docs/TS_DIAGNOSTIC_CODE_STATUS.md — codes referenced from production source; 459 catalog-only remain, but 0 are reachable parity targets (the reachable subset is complete) — ~455 are dead-in-reference + 4 blocked, see docs/TS_DIAGNOSTIC_REACHABILITY.md |
| LSP wire methods | 76 / ~80 — ~95% | SUPPORTED_METHODS in packages/ts_lsp_server/; LSP 3.17 sync/lifecycle complete, notebook + window meta wired, workspaceSymbol/resolve + $/progress + codeAction/resolve + workspace/textDocumentContent (LSP 3.18) |
| Bun runtime — source files present | 1,430 files in packages/runtime/src/ |
live count from scripts/measure-parity.sh --values; audited Bun baseline is 1,193 files |
| Bun runtime — files integrated | 552 / 1,193 — ~46.3% | Home-import-rewritten, Zig 0.17-clean, build-wired, and tested |
Bun compat shim — bun.* symbols |
16 / ~103 — ~15.5% | Tier-0 + Tier-1 (Output, strings, String, AllocationScope, Environment, JSError, create, debugAssert, env_var) lets vendored Bun source compile against Home's stdlib |
Node.js — node:* modules JS-callable |
24 / 47 — ~51% (🟡 subsets) | callable via Home's own JSC realm (home eval / HOME_NATIVE_RUN), unit-tested; see docs/PARITY-NODE.md. Not yet wired into the bun-corpus gate |
| JSC bring-up (Phase 12.2) | JS-callable bridge live | home eval / HOME_NATIVE_RUN run through Home's own JSC; 24 node:* modules + a broad Bun.* surface (spawn/spawnSync/which/file/write/hash/gzipSync/Glob/…) callable & unit-tested. Native subsystems: zlib (std.compress), crypto HMAC/pbkdf2 (std.crypto), spawn (std.process) |
| Language features (capability matrix) | 18 stable / 43 partial / 2 not-yet — 63 total | ~28.6% stable, ~68.3% in progress, ~3.2% not yet (includes TS frontend + Runtime/Bun rows) |
| Total test count | ~8,415 tests (unit + integration + conformance-pin) | ./pantry/.bin/zig build test --summary all on Zig 0.17.0-dev.131. The focused ts_checker suite is 3,025 / 3,025; full exact conformance remains opt-in with 1,036 mismatched fixtures, and the home_rt runtime target needs Bun's JSC/uWS C++ artifacts to link. |
Measured by running the upstream TypeScript conformance corpus through
packages/ts_conformance/. The harness compares byte-for-byte against
upstream .errors.txt baselines in exact mode (HOME_TS_CONFORMANCE_EXACT=1);
coarse mode (HOME_TS_CONFORMANCE_FULL=1 alone) only asserts that we emit
the same families of diagnostics.
| Measurement | Pass rate | Notes |
|---|---|---|
| Coarse mode (5,907 cases) | 5,907 / 5,907 — 100% | Saturated; remains the per-PR merge gate. |
| Exact mode (byte-for-byte, full corpus) | 4,871 / 5,907 — ~82.5% | Ratcheting weekly; 1,036 exact cases remain. |
| Baseline-aware exact categories (19 folders, 586 cases) | 586 / 586 — 100% | apparentType, bestCommonType, recursiveTypes, typeInference, keyof, conditional, instanceOf, widenedTypes, specifyingTypes, primitives, any, import, uniqueSymbol, namedTypes, localTypes, forAwait, unknown, witness, typeAliases, asyncGenerators. |
| Named-category exact survey (4 folders, 86 cases) | 86 / 86 — 100% | assignmentCompatibility 70/70, comparable 13/13, inOperator 2/2, stringLiteral 1/1. |
| Smoke (3 folders, 16 cases) | 16 / 16 — 100% | Per-PR fast path. |
| TS diagnostic-code catalogue | 1,620 / 2,079 emitted — ~77.9% | Mirrors the full upstream code → message table; powers home-lsp hover-on-TS1234. 459 catalog-only entries remain, but 0 are reachable parity targets (the reachable subset is complete): ~455 are dead-in-reference + 4 blocked/subsystem-gated; see docs/TS_DIAGNOSTIC_CODE_STATUS.md + docs/TS_DIAGNOSTIC_REACHABILITY.md. |
Exact mode by 1,000-case slice (snapshot; the per-slice breakdown is recomputed less often than the aggregate above and lags it slightly — re-run the command below to refresh):
| Slice | Pass rate | % |
|---|---|---|
START=0 LIMIT=1000 |
604 / 1,000 | 60.4% |
START=1000 LIMIT=1000 |
611 / 1,000 | 61.1% |
START=2000 LIMIT=1000 |
907 / 1,000 | 90.7% |
START=3000 LIMIT=1000 |
646 / 1,000 | 64.6% |
START=4000 LIMIT=1000 |
864 / 1,000 | 86.4% |
START=5000 LIMIT=907 |
545 / 907 | 60.1% |
Reproduce locally:
HOME_TS_CONFORMANCE_FULL=1 \
HOME_TS_CONFORMANCE_EXACT=1 \
HOME_TS_CONFORMANCE_START=2000 \
HOME_TS_CONFORMANCE_LIMIT=1000 \
./pantry/.bin/zig build test -Dfilter=ts_conformancePhase 12 vendors Bun's Zig source under MIT and rewrites it to compile
against Home's stdlib. The JS-callable bridge is live: home eval and
HOME_NATIVE_RUN=1 home run execute JavaScript through Home's own
JavaScriptCore realm (not system bun), with 24 node:* modules and a
broad Bun.* surface callable and unit-tested. The default home run
still delegates to pantry bun, and the bun-corpus gate still routes
through the bootstrap harness — wiring the realm into those is the next
convergence step (see docs/BUN_PARITY_PLAN.md).
home build app.ts -o app (and the equivalent JS/JSX/TSX module extensions)
now creates a self-contained host executable through LLVM. LLVM compiles the
native launcher, while the binary embeds the entry source and Home's own
JavaScriptCore runtime so JavaScript semantics remain faithful to the runtime.
Arguments and exit status are forwarded to the entrypoint. This first slice is
single-entrypoint; bundling imported files and cross-target builds remain part
of the standalone module-graph work. Native JS/TS builds currently require a
JavaScriptCore-enabled Home compiler plus LLVM/Clang on PATH, and are
available on arm64 and x86-64 macOS/Linux hosts.
| Measurement | Coverage | % |
|---|---|---|
| Runtime Zig source files present | 1,430 files | live packages/runtime/src/**/*.zig count; includes Home glue and staged Bun integration backlog |
| Bun source files integrated | 552 / 1,193 | ~46.3% |
| Subsystems scaffolded | 100 directories under packages/runtime/src/ |
— |
| Functional runtime | 🟡 JS-callable realm live (home eval / HOME_NATIVE_RUN); default home run + corpus gate still delegate |
— |
| JS-callable realm surface | 24 node:* modules + broad Bun.* |
🟡 subsets, unit-tested; see docs/PARITY-NODE.md / docs/PARITY-BUN.md |
| JSC bring-up (Phase 12.2) | 151 files | M1-M6 + JS-callable bridge live (eval/run through Home's own JSC; realm globals: console/process/web/crypto/timers/url/webcore/fetch/Bun/require) |
node:* substrate (Phase 12.7) |
28 files | round-15 landed (buffer, stream, fs, events, util, assert, os, url, querystring, crypto, process, string_decoder, tty + binding files) |
Upstream pinned at fd0b6f1a (see
packages/runtime/UPSTREAM_SHA.txt);
full audit at
packages/runtime/PORT_AUDIT_2026-05-20.md.
The release gate per packages/runtime/README.md:
Bun's test/ corpus must pass 100% with no skips once feature-complete.
Phase-by-phase status:
| Sub-phase | Source under ~/Code/bun/src/ |
Status |
|---|---|---|
| 12.1 — CLI | cli/ |
🚧 scaffold landed |
| 12.2 — JSC bring-up | jsc/, bun.js.zig |
🟡 M6 milestone landed (151 files: JSON + Promise + Iterator + Global helpers); JS-callable bridge live |
| 12.3 — Event loop / IO / async | event_loop/, io/, async/ |
🟡 substrate landing (~30+ leaves ported via wave-19+ grinders) |
| 12.4 — Module loader | resolver/, module_loader.zig |
🚧 blocked on 12.2 |
| 12.5 — Web / HTTP / DNS | web/, http/, csrf/, dns/ |
🚧 blocked on 12.3 |
| 12.6 — Home.* JS surface | bun.zig (renamed to Home.*) |
🚧 blocked on 12.2 |
12.7 — node:* shims |
node/ |
🟡 substrate landing module-by-module (28 files: buffer, stream, fs, events, util, assert, os, url, querystring, crypto, process, string_decoder, tty) |
12.8 — home test runner |
test/ |
🚧 blocked on 12.2 |
| 12.9 — Pantry integration | install/ |
🚧 scaffold in progress |
| 12.10 — CLI surface | cli/ |
🚧 scaffold landed |
| 12.11 — Cross-compile + bundles | build/ |
🚧 not started |
Top-level package that re-exports the minimal Bun surface against
Home's stdlib so vendored Bun source compiles without modification.
The build wires @import("bun") to this shim (see
build.zig:503-510), letting the
Bun bundler vendor files and the
Bun runtime port keep their upstream
imports diff-clean and re-syncable.
| Measurement | Coverage | % |
|---|---|---|
| Symbols implemented | 16 / ~103 | ~15.5% |
| Test surfaces | inline (~9 tests) + bundler-side integration (7 tests) | regression-gated |
Implemented surface (16 symbols across Tier-0 + Tier-1):
| Symbol | Status | Purpose |
|---|---|---|
bun.OOM |
🟢 | error{OutOfMemory} alias for explicit error-return signatures (bun.OOM!void) |
bun.JSError |
🟢 | error{ JSException, OutOfMemory } union for JSC-touching callers |
bun.Environment |
🟢 | Build-time flags (isDebug, isWindows, isMac, ci_assert, enable_logs) |
bun.env_var |
🟢 | Run-time env-var namespace (WANTS_LOUD.get()) |
bun.handleOom |
🟢 | Unwrap OOM-returning calls or panic on OOM for call sites that can't propagate |
bun.default_allocator |
🟢 | Process-wide allocator (re-exports std.heap.smp_allocator) |
bun.assert |
🟢 | Alias for std.debug.assert |
bun.AllocationScope |
🟢 | Allocator-scope wrapper for region-style lifetimes |
bun.Output |
🟢 | Logger / stderr namespace (enable_ansi_colors_stderr, isAIAgent) |
bun.debugAssert |
🟢 | Debug-only assert (compiles away in release builds) |
bun.create |
🟢 | Typed allocator helper: allocator.create + value |
bun.StringHashMapUnmanaged |
🟢 | Alias for the std-lib generic |
bun.String |
🟢 | Interned-string newtype with .static(...) + .slice() |
bun.strings |
🟢 | String utilities (isValidUTF8 so far) |
bun.ast.Index |
🟢 | Strongly-typed source-file / module index with .Int = u32 companion |
bun.fs.Path |
🟡 | Path record; Tier-0 callers read only .text (struct will grow per tier) |
Each subsequent tier opens the door for more vendored Bun files to
compile. See docs/PARITY-BUN-COMPAT.md
for the per-symbol drill-down, planned Tier-2+ categories
(bun.JSC.*, bun.path, bun.options, bun.resolver,
bun.MutableString, bun.bake, bun.css, bun.transpiler,
bun.SourceMap), and the test wiring.
Node's node:* namespace lands as part of the Bun runtime port (Bun
ships node:* shims natively, which we vendor verbatim). Numbers
below are Zig-side only; the JS-visible node:* surface attaches once
JSC's JS-callable bridge ships (Phase 12.2 has reached M6 — JSON +
Promise + Iterator + Global helpers — across 151 files).
| Measurement | Coverage | Notes |
|---|---|---|
| Node binding files ported | 28 files | path, Stat, StatFS, dir_iterator, time_like, fs_events, os_constants, nodejs_error_code, node_fs_constant, node_net_binding, node_error_binding, uv_signal_handle_windows, types, util/parse_args_utils, assert/myers_diff, plus top-level buffer.zig, stream.zig, fs.zig, events.zig, util.zig, assert.zig, os.zig, url.zig, querystring.zig, crypto.zig, process.zig, string_decoder.zig, tty.zig (Phase 12.7 round-15). |
Functional node:* modules |
🚧 Awaiting JSC JS-callable bridge | Pantry CLI replaces npm install / bun install; everything else routes through the Bun runtime port once JSC ships its JS bridge (Phase 12.2 milestones M3-M6 are in; the JS-callable wire-up is the remaining piece). |
| Measurement | Coverage | % |
|---|---|---|
| Wire methods routed | 76 / ~80 | ~95% |
Routed methods (SUPPORTED_METHODS in
packages/ts_lsp_server/src/ts_lsp_server.zig):
hover, definition, declaration, typeDefinition, implementation,
references (cross-file), completion + completionItem/resolve,
signatureHelp, semanticTokens (full + delta + range), inlayHint
(+ resolve), codeAction, codeLens (+ resolve), documentLink (+ resolve),
foldingRange, selectionRange, linkedEditingRange, documentHighlight,
documentSymbol + workspace/symbol, rename + prepareRename,
prepareCallHierarchy + incoming/outgoingCalls,
prepareTypeHierarchy + supertypes/subtypes, willSaveWaitUntil,
willRenameFiles, executeCommand, moniker (LSIF), inlineValue,
inlineCompletion, formatting + onTypeFormatting,
documentColor + colorPresentation, pull-based diagnostic +
workspace/diagnostic, lifecycle (initialize / initialized /
shutdown / exit), synchronization (didOpen / didChange / didClose /
publishDiagnostics).
Remaining surface: quick-fix breadth (organize imports + add
import + add explicit type annotation landed; fix-all,
missing-return-type, infer-parameter-types pending), FS-event-driven
push diagnostics, full formatter pass (current formatDocument
returns source unchanged), richer auto-import completion via
cross-file interner search.
16 language rows from the Capability Matrix:
| Status | Count | % |
|---|---|---|
| ✅ Stable | 3 | 18.8% |
| 🚧 In progress / partial | 12 | 75.0% |
| ❌ Not yet | 1 | 6.3% |
Per-feature:
| Feature | Status |
|---|---|
| Lexer (full token set, escapes, line/col tracking) | ✅ Stable |
| Recursive-descent parser with error recovery | ✅ Stable |
| Type inference (primitives, structs, enums, arrays) | ✅ Stable |
Pattern matching (match over enums, primitives, wildcards) |
🚧 In progress |
| Closures | 🚧 In progress |
Traits / impl blocks |
🚧 In progress |
| Trait objects / dynamic dispatch | 🚧 In progress |
| Generics (functions and types) | 🚧 In progress |
| Comptime evaluation | 🚧 In progress |
Macros (todo!, assert!, unreachable!, …) |
🚧 In progress |
Null-safety operators (?., ?:, ??, ?[]) |
🚧 In progress |
Result types and ? propagation |
🚧 In progress |
| Async / await | 🚧 In progress |
| Ownership / move checking | 🚧 In progress |
| Borrow checker | 🚧 In progress |
| Const generics | ❌ Not yet |
7 codegen rows:
| Status | Count | % |
|---|---|---|
| ✅ Stable | 1 | 14.3% |
| 🚧 In progress / partial | 6 | 85.7% |
Per-target:
| Target | Status |
|---|---|
| Tree-walking interpreter | ✅ Stable |
| x86-64 native codegen | 🚧 Substantial (primary target) |
| arm64 codegen | 🚧 In progress (Path B-lite M1-M11 shipped) |
| WebAssembly codegen | 🚧 Stub |
| LLVM backend | 🚧 JS/TS native launcher shipped; Home AST lowering in progress |
| ELF object emission | 🚧 In progress |
| Mach-O object emission | 🚧 In progress |
11 tooling rows:
| Status | Count | % |
|---|---|---|
| ✅ Stable | 2 | 18.2% |
| 🚧 In progress / partial | 9 | 81.8% |
Per-tool:
| Tool | Status |
|---|---|
home check (type-check) |
✅ Stable |
home run (interpret) |
✅ Stable |
home build (native binary) |
🚧 Home native codegen + self-contained LLVM JS/TS entrypoints |
home test runner |
🚧 In progress |
| Formatter | 🚧 In progress |
| Linter | 🚧 In progress |
| LSP / IDE integration | 🚧 In progress (see LSP coverage) |
| VSCode extension | 🚧 In progress |
| REPL | 🚧 In progress |
Package manager (pkg) |
🚧 In progress |
| Incremental compilation / IR cache | 🚧 In progress |
9 stdlib categories tracked in the capability matrix (the project ships
136 packages under packages/ — most are 🚧 until end-to-end validated):
| Status | Count | % |
|---|---|---|
| ✅ Stable | 3 | 33.3% |
| 🚧 In progress / partial | 6 | 66.7% |
Per-module:
| Module | Status |
|---|---|
Core primitives (int, float, bool, string, arrays) |
✅ Stable |
String methods (trim, upper, split, …) |
✅ Stable |
Range methods (len, step, contains, …) |
✅ Stable |
| HTTP server | 🚧 In progress |
| Database / SQL | 🚧 In progress |
| Threading | 🚧 In progress |
| FFI / C interop | 🚧 In progress |
| Audio / video / graphics | 🚧 In progress |
| Kernel / OS modules | 🚧 In progress |
All 63 rows from docs/CAPABILITY_MATRIX.md
(language + codegen + tooling + stdlib + TypeScript frontend + runtime/Bun):
| Status | Count | % |
|---|---|---|
| ✅ Stable | 18 | ~28.6% |
| 🚧 In progress / partial | 43 | ~68.3% |
| ❌ Not yet | 2 | ~3.2% |
The conservative bias is intentional: anything not exercised by an example or test stays 🚧 even when the underlying code is largely there.
Home is being extended with a drop-in tsc / tsgo compatible
TypeScript frontend. The plan is documented in
docs/TS_PARITY_PLAN.md. Phase 4.5 is
substantially complete: a home tsc driver wires lex → parse →
bind → check → emit end-to-end with multi-file program graph,
parallel compile, source maps, tsc-compatible diagnostics, and a
zig-dtsx fast path for .d.ts emission.
Top-level shape (each link is a Zig package with its own tests):
packages/ts_lexer— full ES2024 + TS keyword scanner (16-byte tokens, comptime perfect-hash keywords)packages/ts_parser— recursive-descent statements, Pratt expressions, JSX, generics, decorators, full type-annotation grammarpackages/hir— SoA HIR (21 B/node hot footprint, gated at compile time)packages/binder— symbol table with three TS meaning-spaces and declaration mergingpackages/ts_checker— type interner, relation cache, expression-level checkingpackages/ts_emit— streaming JS pretty-printer, V3 source maps, symbol-driven.d.ts, zig-dtsx fast pathpackages/ts_driver— single-file end-to-end compile (lex → parse → bind → check → emit)packages/ts_program— multi-file program graph with parallel compileAllParallelpackages/ts_resolver— module resolution across the five tsc strategies + path mappingpackages/ts_diagnostics— tsc-compatible diagnostic formatting (default + pretty)packages/ts_cli—home tscCLI flag surfacepackages/ts_conformance— tsc-baseline conformance harnesspackages/ts_lsp— Language Server query surface (hover, definition, references, completion, codeActions, semantic tokens, inlay hints, folding, document symbols, …)packages/ts_lsp_server— JSON-RPC framing + method dispatch (76 LSP-spec methods routed; see parity status)packages/ts_cache— content-addressed compilation cache with sharded disk persistencepackages/ts_watch— pluggableStatFs+ watcher driving incremental recompiles inhome-tsc --watchpackages/d_hm— Home declaration files (the.d.tsanalogue for.home)pantry/zig-dtsx— vendored as a pantry dep; powers the.d.tsfast path (15-19× faster than tsgo per published benchmarks)
home-tsc and home-lsp ship as standalone binaries — see the
./pantry/.bin/zig build invocation to compile them; they
install into zig-out/bin/.
curl -fsSL https://raw.githubusercontent.com/home-lang/home/main/install.sh | bashThe installer detects your platform, downloads a release tarball from GitHub
Releases, verifies its checksum, and installs the home binary to
~/.home/bin. It supports macOS (Intel + Apple Silicon), Linux (x64 + arm64),
and Windows (x64 + arm64, via Git Bash / WSL).
Useful environment variables:
HOME_VERSION=v0.1.0(or0.1.0) — pin a specific release tag (default:latest)HOME_INSTALL_DIR=/opt/home— override install location (default:~/.home)HOME_BIN_DIR=/usr/local/bin— override where the binary is placed
git clone https://github.com/home-lang/home.git
cd home
pantry install # installs the pinned Zig 0.17 dev toolchain
./pantry/.bin/zig build # ./pantry/.bin/zig is a stable symlink to the pinned toolchain
# Run an example
./zig-out/bin/home build examples/fibonacci.home
./examples/fibonacciUseful commands:
./pantry/.bin/zig build— build the compiler./pantry/.bin/zig build test— run the unit-test suite./pantry/.bin/zig build examples— run the native example executables (http_router, craft, fullstack, queue)./pantry/.bin/zig build run -- examples/fibonacci.home— build, then run a filescripts/check-examples.sh—home checkevery.homeexample./pantry/.bin/zig build -Dgenerals=true generals— opt in to the C&C Generals example (needs Xcode frameworks)
fn main() {
print("Hello, Home!")
}
let name = "Alice" // immutable by default
let mut counter = 0 // mutable
let age: int = 25 // explicit type
const PI = 3.14159 // compile-time constant
// if statements (parentheses required)
if (x > 5) {
print("big")
} else {
print("small")
}
// while loops
while (count < 10) {
count = count + 1
}
// for loops
for (item in items) {
print(item)
}
for (i in 0..10) {
print(i)
}
// for with index
for (index, item in items) {
print("{index}: {item}")
}
fn add(a: int, b: int): int {
return a + b
}
fn greet(name: string) {
print("Hello, {name}!")
}
// default parameter values
fn greet_with_default(name: string = "World") {
print("Hello, {name}!")
}
greet_with_default() // prints: Hello, World!
greet_with_default("Alice") // prints: Hello, Alice!
// async functions
fn fetch_data(): async Result<Data> {
let response = await http.get("/api/data")
return response.json()
}
struct Point {
x: int
y: int
}
struct User {
id: i64
name: string
email: string
}
let origin = Point { x: 0, y: 0 }
let user = User { id: 1, name: "Alice", email: "alice@example.com" }
enum Color {
Red,
Green,
Blue,
Custom(r: int, g: int, b: int)
}
enum Result<T, E> {
Ok(T),
Err(E)
}
match value {
Ok(x) => print("Got: {x}"),
Err(e) => print("Error: {e}")
}
match color {
Color.Red => print("red"),
Color.Green => print("green"),
Color.Blue => print("blue"),
Color.Custom(r, g, b) => print("rgb({r}, {g}, {b})")
}
If and match can be used as expressions that return values:
// if expression
let status = if (code == 200) { "ok" } else { "error" }
// match expression
let name = match x {
1 => "one",
2 => "two",
_ => "other"
}
// Elvis operator (?:) - returns right side if left is null
let name = user?.name ?: "Anonymous"
// Null coalescing (??) - same as Elvis
let value = maybeNull ?? defaultValue
// Safe navigation (?.) - returns null if object is null
let city = user?.address?.city
// Safe indexing (?[]) - returns null if index out of bounds
let first = items?[0]
let safe = items?[10] ?: defaultItem
fn read_file(path: string): Result<string, Error> {
let file = fs.open(path)? // ? propagates errors
return Ok(file.read_all())
}
// handle errors
match read_file("config.home") {
Ok(content) => process(content),
Err(e) => print("Failed: {e}")
}
// or with default
let content = read_file("config.home").unwrap_or("default")
let numbers = [1, 2, 3, 4, 5]
let first = numbers[0]
let slice = numbers[1..4] // [2, 3, 4]
for (n in numbers) {
print(n)
}
// Array methods
numbers.len() // 5
numbers.is_empty() // false
numbers.first() // 1
numbers.last() // 5
let s = " Hello World "
// Length
s.len() // 15
// Case conversion
s.upper() // " HELLO WORLD "
s.lower() // " hello world "
// Trimming
s.trim() // "Hello World"
s.trim_start() // "Hello World "
s.trim_end() // " Hello World"
// Searching
s.contains("World") // true
s.starts_with(" H") // true
s.ends_with(" ") // true
// Splitting and replacing
"a,b,c".split(",") // ["a", "b", "c"]
s.replace("World", "Home") // " Hello Home "
// Other methods
"ab".repeat(3) // "ababab"
s.is_empty() // false
s.char_at(2) // "H"
"hello".reverse() // "olleh"
// Method chaining
" HELLO ".trim().lower() // "hello"
// Power operator (**)
let squared = 5 ** 2 // 25
let cubed = 2 ** 3 // 8
let power10 = 2 ** 10 // 1024
// Integer division (~/)
let result = 7 ~/ 2 // 3 (truncates toward zero)
let another = 17 ~/ 5 // 3
// Standard operators
let sum = 10 + 5 // 15
let diff = 10 - 3 // 7
let prod = 4 * 3 // 12
let quot = 10 / 4 // 2.5 (regular division)
let rem = 10 % 3 // 1 (modulo)
// Create ranges
let r = 0..10 // exclusive: 0,1,2,...,9
let inclusive = 0..=10 // inclusive: 0,1,2,...,10
// Range methods
r.len() // 10
r.first() // 0
r.last() // 9
r.contains(5) // true
r.contains(10) // false (exclusive)
// Step through range
let stepped = (0..10).step(2)
stepped.to_array() // [0, 2, 4, 6, 8]
// Inclusive range
inclusive.len() // 11
inclusive.contains(10) // true
inclusive.last() // 10
fn map<T, U>(items: []T, f: fn(T): U): []U {
let result = []U.init(items.len)
for (i, item in items) {
result[i] = f(item)
}
return result
}
struct Stack<T> {
items: []T
fn push(self, item: T) {
self.items.append(item)
}
fn pop(self): Option<T> {
return self.items.pop()
}
}
comptime fn factorial(n: int): int {
if (n <= 1) {
return 1
}
return n * factorial(n - 1)
}
const FACT_10 = factorial(10) // computed at compile time
import http { Server, Response }
fn main() {
let server = Server.bind(":3000")
server.get("/", fn(req) {
return "Hello from Home!"
})
server.get("/users/:id", fn(req): Response {
let id = req.param("id")
return Response.json({ id: id })
})
server.listen()
}
import database { Connection }
fn main() {
let db = Connection.open("app.db")
db.exec("CREATE TABLE users (id INTEGER, name TEXT)")
let stmt = db.prepare("INSERT INTO users VALUES (?, ?)")
stmt.bind(1, 42)
stmt.bind(2, "Alice")
stmt.execute()
let users = db.query("SELECT * FROM users")
for (row in users) {
print("User: {row.name}")
}
}
fn fetch_users(): async []User {
let response = await http.get("/api/users")
return response.json()
}
fn main(): async {
let users = await fetch_users()
for (user in users) {
print(user.name)
}
}
home/
├── src/main.zig # CLI entry point
├── packages/ # 130+ Zig packages, each with its own tests
│ ├── lexer/ # Home tokenization
│ ├── parser/ # Home AST generation
│ ├── ast/ # Home syntax tree types
│ ├── types/ # Home type system
│ ├── codegen/ # Native code generation (x64 + arm64)
│ ├── interpreter/ # Tree-walking execution
│ ├── diagnostics/ # Error reporting
│ ├── ts_lexer/ # TS scanner (full ES2024 + TS keywords)
│ ├── ts_parser/ # TS parser (statements, expressions, JSX, generics)
│ ├── ts_checker/ # TS type interner, relation cache, expression typing
│ ├── ts_emit/ # JS + .d.ts emit (V3 source maps, zig-dtsx fast path)
│ ├── ts_driver/ # End-to-end per-file lex→parse→bind→check→emit
│ ├── ts_program/ # Multi-file graph + parallel compile + watch
│ ├── ts_resolver/ # Module resolution (5 tsc strategies + paths)
│ ├── ts_lsp/ # Language Server query surface
│ ├── ts_lsp_server/ # JSON-RPC framing + dispatch
│ ├── ts_conformance/ # tsc-baseline conformance harness
│ ├── hir/ # SoA HIR shared between both frontends
│ ├── binder/ # Symbol table (3 TS meaning-spaces, decl merging)
│ └── ... # http, database, async, ffi, graphics, …
├── examples/ # Example programs
├── tests/ # Integration tests
└── stdlib/ # Standard library
- Pantry-installed Zig 0.17 dev (for building the compiler)
# Pulls the pinned Zig 0.17 dev build from Pantry.
pantry install# Build the compiler
./pantry/.bin/zig build
# Run tests
./pantry/.bin/zig build test
# Check all .home examples through `home check`
scripts/check-examples.sh
# Build and run an example
./pantry/.bin/zig build run -- examples/fibonacci.home.home- Standard source file extension.hm- Short alternative
- Fast compilation - Incremental builds with IR caching
- Memory safety - Ownership and borrowing without ceremony
- Native performance - Compiles to native x64 code
- Modern syntax - TypeScript-inspired, clean and readable
- Pattern matching - Exhaustive match expressions
- Expression-oriented - If and match as expressions
- Null safety - Elvis (
?:), safe navigation (?.), safe indexing (?[]) - Async/await - Zero-cost async programming
- Generics - Type-safe generic functions and types
- Comptime - Compile-time code execution
- Error handling - Result types with
?propagation - Power operator —
**for exponentiation (2 ** 10) - Integer division -
~/for truncating division - Range methods -
.len(),.step(),.contains(),.to_array() - Default parameters -
fn greet(name: string = "World") - String methods -
.trim(),.upper(),.split(), and more
Home is under active development. For a granular, conservative view of what
works today vs. what is partial, in progress, or not yet started, see the
parity status section above (percentage-based, per-area
tables) plus the detailed per-feature pages in
docs/PARITY-TYPESCRIPT.md,
docs/PARITY-NODE.md,
docs/PARITY-BUN.md,
docs/PARITY-BUN-COMPAT.md, and
docs/CAPABILITY_MATRIX.md. Release notes
live in CHANGELOG.md.
Contributions welcome! See CONTRIBUTING.md.
MIT License - see LICENSE
