A modern programming language for systems, apps, and games β
the speed of Zig, the safety of Rust, the joy of TypeScript.
And a drop-in replacement for tsc.
Website Β· Documentation Β· Getting started Β· Parity status Β· Benchmarks Β· Changelog
Home is two things built from one Zig toolchain:
- A TypeScript compiler.
home tscreads your existingtsconfig.json, acceptstsc's flags, and prints the sameTSxxxxdiagnostics with the same exit status. Corpus parity is being remeasured after removing harness exceptions that fabricated matches. Previous corpus pass counts are withdrawn. Its current performance is measured against bothtscand native TypeScript 7 (tsgo) in the admitted benchmark suite below. - A native language.
.homefiles compile to native binaries with no garbage collector and no runtime shipped beside them.
Status: under active development. The TypeScript front end, lexer, parser, type inference, and interpreter are usable today; native codegen, tooling, and the Bun-compatible runtime are still maturing. Project status has the short version and Parity status has every number with the harness that produces it.
Everything ships in the one home binary. Swap the command, keep everything
else:
- npx tsc -p tsconfig.json --noEmit
+ home tsc -p tsconfig.json --noEmithome tsc # build the project in ./tsconfig.json
home tsc --noEmit # type-check only β same diagnostics, codes and exit status
home tsc --watch # incremental rebuilds on change
home tsc -b # project references / build mode
home tsc --init # write a starter tsconfig.json
home lsp --stdio # one language server for TypeScript and .home files
home run server.ts # run TypeScript on Home's own JavaScriptCore realmInvoked under the name tsc (or home-tsc), home behaves exactly like
tsc, so a symlink is a literal drop-in for scripts and tools that call tsc:
ln -s "$(command -v home)" /usr/local/bin/tscThe familiar options work as they do in tsc: -p/--project, --strict,
--target, --module, --moduleResolution, --outDir, --declaration,
--sourceMap, --jsx, --skipLibCheck, --showConfig, --listFiles,
--traceResolution, and the rest of the option table. Output uses the
reference compiler's wording, so CI problem matchers and editor integrations
keep working unchanged:
src/api.ts(12,7): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
Parity is measured against TypeScript's own conformance corpus, not tests we wrote ourselves. Exact mode diffs every diagnostic β code, message, file, line, and column β byte-for-byte against baselines generated by the reference compiler.
| Suite | Result |
|---|---|
| Upstream conformance corpus, exact byte-for-byte | Withdrawn; fresh measurements pending after removing fabricated results |
| Upstream conformance corpus, diagnostic families | Withdrawn; harness contained expected-result overrides |
Baseline-aware .errors.txt comparison, 19 folders |
Previous result withdrawn; revalidation pending |
| Diagnostic codes the reference compiler can emit | 100% β 0 reachable codes left ΒΉ |
The default smoke/category gates run in the repository test suite. Exact mode is opt-in, split into bounded slices, and any diagnostic mismatch now fails the test process. Previous exact-prefix and coarse-corpus claims are invalidated by fixture-name replacements, baseline-derived diagnostics, and diagnostic filtering. Their removal and fresh validation are tracked in #832. Run bounded exact slices with:
git submodule update --init --recursive _submodules/typescript-go
HOME_RUN_MAX_MB=3840 \
scripts/ts-conformance-exact.sh 0 3220 200Explicit full-corpus runs fail if the pinned cases or generated baselines are
missing. HOME_TS_SUITE_ROOT can select another initialized TypeScript-Go tree.
ΒΉ Home emits 1,620 of the 2,079 codes in TypeScript's message catalog. The other 459 are not a backlog: about 455 are dead in the reference compiler (superseded wording it never produces) and 4 are gated on unwired subsystems. See diagnostic reachability.
Type-checking time on the reproducible
bench/vs_tsgo suite: TypeScript 6.0.3 (tsc), native
TypeScript 7.0.2 (tsgo), Home, Rust tsc-rs 0.1.0 (TypeScript 7.1.0-dev),
and Bun 1.4.3-canary.1+bd599f5af on identical strict, no-emit projects.
Resumed result 20261011T232901Z-resumed ran on an Apple M3 Pro / Mac15,6 with 11 logical
cores and Darwin 27.0.0 arm64. TypeScript 7 runs directly as a native binary.
Values are medians of 30 fresh processes after three warmups; lower is better.
The run was interrupted and continued without repeating recorded samples.
Shared-host load and the pause limit interpretation; this is not a causal patch comparison.
| Workload | tsc 6.0.3 |
Native tsgo 7.0.2 |
Home | Rust tsc-rs | Bun canary | Home vs fastest competitor |
|---|---|---|---|---|---|---|
| Startup (one small file) | 255.6 ms | 28.7 ms | 10.5 ms | 23.7 ms | 22.8 ms | 2.18Γ faster |
| 256 independent files | 1,067.2 ms | 93.8 ms | 99.8 ms | 55.1 ms | 51.1 ms | 1.95Γ slower |
| 128-module import chain | 974.7 ms | 74.0 ms | 91.2 ms | 63.3 ms | 117.9 ms | 1.44Γ slower |
| 64 modules through 8 barrel re-exports | 550.7 ms | 37.6 ms | 72.4 ms | 31.5 ms | 30.3 ms | 2.39Γ slower |
| Deep conditional / mapped / template types | 1,898.3 ms | 127.5 ms | 138.2 ms | 72.5 ms | 70.7 ms | 1.95Γ slower |
| Recursive generics | 194.4 ms | 47.2 ms | 17.9 ms | 39.1 ms | 12.7 ms | 1.41Γ slower |
| Checked JavaScript with JSDoc | 261.3 ms | 29.1 ms | 32.6 ms | 29.0 ms | 17.4 ms | 1.88Γ slower |
| Control-flow narrowing (256 unions) | 1,502.8 ms | 137.5 ms | 144.3 ms | 100.8 ms | 55.3 ms | 2.61Γ slower |
| Null-safe access (256 families) | 286.9 ms | 35.9 ms | 29.2 ms | 31.9 ms | 22.9 ms | 1.28Γ slower |
| 2,048 type-predicate families | 3,215.9 ms | 789.8 ms | 596.0 ms | 680.4 ms | 436.2 ms | 1.37Γ slower |
In this dated matrix, Home has the lowest median on 1 / 20 admitted workloads (startup) and is faster than native TypeScript 7 on 9 / 20. These are descriptive medians, not statistical-significance claims. The complete table, methodology, machine and toolchain versions are in TypeScript performance. All 600 rounds / 3,000 samples / 150 admissions are retained; no timings were repeated or filtered. All original checkpoint bytes and supplements are checksum-verified. Current fastest-competitor gaps include null-safe access 1.28Γ, checked JS 1.88Γ and interfaces 1.81Γ slower, tracked under #864. This is a full competitor comparison, not a causal patch A/B. The matrix uses protocol 5 with 150/150 pre-timing admissions, checking inferred locals and optional-call results. See the new admission contract. The earlier native null-safe profile uses one unchanged compiler process and two fixed windows after 36 admission checks. Displayed PCs map to namespace-import scanning even on the import-free scaled input; this is an investigation lead, not a CPU-share or speedup claim.
The latest source-native checked-JS profile includes the recursive-interface fix and still displays root require-binding scans and local JSDoc work. It is a new image, not a refresh of the matrix above; it does not establish a speedup or whole-run CPU share. The earlier profile retains the exact compiler measured by that matrix.
| Latest-source diagnostic check | Result |
|---|---|
| Unchanged 8,192-family positive/negative and native protocol controls | 6/6 and 30/30 pass |
| Fixed-window native profile | One process, two windows, 293 mapped symbol groups; zero benchmark timing samples |
Both windows and all original diagnostics remain in the raw evidence.
The JSDoc attachment memo under #882 is rejected and restored after all 880 fixed pairs completed. Correctness passed, but the primary interval spans zero and three independent intervals show losses. No compiler code was adopted.
| Rejected independent comparison, 30 pairs | Parent median | Candidate median | Mean-saving 95% interval |
|---|---|---|---|
| Official checked JS | 30.935 ms | 31.232 ms | -2.001 to +0.011 ms |
| Control flow | 28.467 ms | 28.195 ms | -1.560 to -0.099 ms |
| Overload resolution | 27.877 ms | 28.729 ms | -1.190 to -0.084 ms |
| Recursive generics | 15.989 ms | 16.205 ms | -0.720 to -0.198 ms |
Medians do not determine paired-mean intervals. All 44 phases / 880 pairs / 264 warmups are retained without timing repeats or filtering. See the complete report and raw evidence. This Home-only A/B does not refresh the competitor ranking above.
The coherent root-receiver lookup candidate under #881 is unqualified and restored. Its official checked-JS independent interval spans zero; scaling gains cannot replace that frozen primary-target requirement.
| Unqualified exact-parent comparison | Parent median | Candidate median | Mean-saving 95% interval |
|---|---|---|---|
| Official checked JS independent, 30 pairs | 31.620 ms | 31.343 ms | -0.142 to +4.473 ms |
| Startup screen, 10 pairs | 3.007 ms | 3.407 ms | -0.567 to -0.274 ms |
| Startup independent, 30 pairs | 3.416 ms | 3.161 ms | +0.088 to +0.379 ms |
| 512-family JS independent, 30 pairs | 132.317 ms | 128.076 ms | +3.438 to +6.688 ms |
| 8,192-family JS independent | β | β | Incomplete: guard124; 27 complete pairs plus empty raw retained |
All 877 complete pairs / 264 warmups remain, with no measurement repeats. No compiler code was adopted. See the complete qualification report and raw evidence. The complete competitor ranking above is unchanged.
The live-body supported-write proof is now accepted under #864: the independent official null-safe workload has a 34.4% lower median, with 30/30 faster pairs.
| Accepted write-proof comparison | Parent median | Candidate median | Mean-saving 95% interval |
|---|---|---|---|
| Null-safe independent, 30 pairs | 33.131 ms | 21.737 ms | +11.347 to +11.772 ms |
| CommonJS independent, 30 pairs | 17.561 ms | 17.825 ms | -0.322 to +0.049 ms |
| Class hierarchy independent, 30 pairs | 23.425 ms | 23.639 ms | -0.404 to +0.185 ms |
All 530 pairs / 280 admissions are retained with no filtering or timing repeats. No independent risk interval is wholly negative; zero-spanning intervals do not establish equivalence. See the complete accepted report and raw evidence. This Home-only A/B does not refresh the competitor ranking above. The new checked-JS native profile under #854 verifies one unchanged compiler process after 36 admissions. It identifies repeated require-binding root scans and local JSDoc work; no CPU-share or new speedup is claimed. The subsequent stateless JSDoc single-line-scan candidate was rejected: its small checked-JS gain came with a confirmed startup loss.
| Rejected single-line-scan comparison | Parent median | Candidate median | Mean-saving 95% interval |
|---|---|---|---|
| Checked JS independent, 30 pairs | 28.102 ms | 27.817 ms | +0.039 to +0.479 ms |
| Startup independent, 30 pairs | 2.928 ms | 2.942 ms | -0.157 to -0.003 ms |
| Overloads independent, 30 pairs | 25.271 ms | 25.575 ms | -0.482 to +0.457 ms |
All 590 pairs / 284 admissions remain with no filtering or timing repeats. Source and native are restored; the ranking above is unchanged. See the complete rejection report and raw evidence.
Declaration/context identity recovery under #879
landed in 4b4060e05 after complete source gates, strict real-CLI admission and
the frozen exact-parent regression-risk protocol. The prior competitor ranking
above measures its frozen compiler image. The original interrupted run remains
unranked separately; the complete continuation preserves every recorded sample.
| Landed owned alias qualification | Result |
|---|---|
| Checker / Program / driver / CLI / entrypoint / harness | 4,568 / 265 / 201 / 78 / 46 / 147 tests pass |
| Extended / six-image protocol-5 admission | 294/294 and 180/180 pass; unchanged inputs/provenance |
| Exact-parent risk qualification | 590 pairs retained; no wholly negative independent interval; inconclusive is not equivalence |
| Full unchanged Zod | 233 TS + two HM9002; unadmitted and untimed |
| New-source five-pin matrix | Complete paused continuation: 3,000 samples; 1/20 lowest medians, 9/20 faster than TS7 (report) |
See the complete qualification and timing report and complete raw evidence. The forward-alias diagnosis and earlier main integration remain separate historical snapshots. The earlier failed controls remain documented separately.
The earlier live-HIR import-absence candidate under #864 was rejected: its independent null-safe target did not establish the required gain.
| Phase and workload | Parent median | Candidate median | Paired mean-saving 95% interval |
|---|---|---|---|
| Null-safe screen, 10 pairs | 32.464 ms | 32.544 ms | -0.062 to +0.399 ms |
| Null-safe independent, 30 pairs | 34.038 ms | 33.841 ms | -0.106 to +2.981 ms |
| Re-export screen, 10 pairs | 11.612 ms | 12.304 ms | -0.973 to -0.058 ms |
| reexport graph independent, 30 pairs | 12.191 ms | 12.248 ms | -0.296 to +0.595 ms |
| destructuring independent, 30 pairs | 15.484 ms | 15.683 ms | -0.255 to +0.048 ms |
| interface composition independent, 30 pairs | 35.836 ms | 35.382 ms | +0.087 to +0.959 ms |
All 530 pairs / 280 admissions remain, including the adverse screen and the 60.264 ms parent target observation. Candidate source and binary are restored; no timings were repeated or filtered. See the complete rejection report and raw evidence. Zero-spanning intervals do not establish equivalence; this Home-only A/B does not change the separate competitor ranking.
The large-predicate
scaling regression was fixed by the lazy overload index in
#837; the expanded competitor
matrix in #838 exposes the next
performance gaps. Export-owner reuse in
#839 improves the unchanged
re-export graph by 1.232Γ in independent same-parent paired confirmation.
The current validation-protocol-4 matrix measures source 0d2b0097a (compiler 11055ba47), including
the landed #853/#854 indexes and later #846 correctness work, but neither
rejected presence cache. It is not a patch A/B. Its checked-JS median remains
2.03Γ slower than the fastest competitor; null-safe access 1.97Γ,
interfaces 1.95Γ, TSX 1.80Γ, and class hierarchy 1.70Γ remain gaps.
CommonJS is 1.49Γ slower. The earlier nested-owner
experiment measures source 30d3824da, against exact parent eaaddf213.
The initial overload regression warning and all ten targeted rechecks are
retained in the docs; CommonJS's recheck has a 0.7% slower median. Cross-run
differences are not patch A/Bs. The export-fact depth cutoff is removed in
source 929d46a67 (#843),
with corrected ambient enum diagnostics/config forwarding
(#844). This later correctness
checkpoint is not a new five-compiler matrix and shows no clear graph speedup:
| Unchanged exact-parent confirmation | Parent 53167b7e5 |
Source 929d46a67 |
Observed outcome |
|---|---|---|---|
| Official re-export graph (30 pairs) | 13.802 ms | 14.197 ms | 2.9% slower median; interval spans zero |
| 4,096-module scale (10 pairs) | 1,384.203 ms | 1,405.088 ms | 1.5% slower median; interval spans zero |
All 30 original TypeScript oracle cases match; that earlier snapshot's
ordinary .ts default-import gate failed and is tracked in
#845. The large-predicate
screen's 3.1% slower warning and 0.5% slower independent recheck remain in
the full correctness/cost report.
Older hosts, competitor sets, and launcher modes are not
mixed with this snapshot.
Later source 206cdf1aa (#845/#846) matches all
105 native TS 7 oracle cases and 86 shared-config TS 6 cases. The 19
remaining cases retain the documented TS 6/7 option-dialect difference; they
are not semantic admissions. Its unchanged-workload exact-parent costs show
no demonstrated speedup:
Default-owner confirmation versus parent b6e34fc68 |
Parent | Candidate | Outcome |
|---|---|---|---|
| Official re-export graph (30 pairs) | 13.293 ms | 13.399 ms | 0.8% slower median; interval spans zero |
| 4,096-module scale (10 pairs) | 1,310.054 ms | 1,299.988 ms | 0.8% faster median; interval spans zero |
The large-predicate 3.5% slower screen and 0.9% slower independent recheck, complete oracle/version distinctions and raw evidence are in the default-owner correctness/cost report.
Two later CommonJS path-index prototypes were rejected, not shipped:
| Prototype, independent same-parent confirmation | CommonJS median | Large-predicate recheck |
|---|---|---|
| Inline index | 5.3% faster | 1.3% slower; negative saving interval |
| Lazy pointer index | 5.2% faster | 1.6% slower; negative saving interval |
All observations and the unaccepted five-compiler run are preserved in the rejection report under #848. Compiler behavior was restored; only general path-matching tests remain.
A third design now ships: Program owns one canonical, extension-normalized CommonJS export table, while each checker borrows it and performs binary-range lookups. It preserves original collection order for metadata precedence and does not allocate a per-checker index.
| Accepted exact-parent result | Parent | Candidate | Paired evidence |
|---|---|---|---|
| Official CommonJS graph | 34.325 ms | 33.478 ms | 25/30 wins; saving interval +0.429 to +1.255 ms |
| 1,024-family independent follow-up | 563.116 ms | 473.763 ms | 30/30 wins; saving interval +79.260 to +93.304 ms |
The first 10-pair scale phase, including two candidate outliers, is retained and reported as inconclusive rather than replaced. The 20-family screen plus 30-pair deep-type and large-predicate rechecks found no independently confirmed regression. See the accepted #848 report and raw evidence.
A grouped require-binding index now removes another source-root scan without changing the ordered scanner's result. The index stores candidates in a flat arena with per-local-name linked buckets, preserves same-section precedence and cross-section conflict handling, and falls back to the complete scanner if an allocation fails.
| Accepted #849 exact-parent result | Parent | Candidate | Paired evidence |
|---|---|---|---|
| Official CommonJS graph | 40.968 ms | 40.719 ms | 15/30 wins; interval β1.995 to +1.931 ms |
| 1,024-family independent follow-up | 529.868 ms | 519.387 ms | 19/30 wins; interval β16.975 to +30.202 ms |
| 4,096-family independent confirmation | 6,103.936 ms | 5,980.145 ms | 22/30 wins; saving interval +23.185 to +209.313 ms |
The official and 1,024-family observations are retained as inconclusive; only the 4,096-family result demonstrates a gain. Seven independent regression rechecks all span zero. See the accepted #849 report and raw evidence.
An untimed C++ candidate audit keeps incomplete checking out of the ranking:
| Candidate / source pin | Positive projects | Negative controls | Timing admission |
|---|---|---|---|
OnlySpecs C++ / 8fd72a2a |
20/20 accepted | 0/8 rejected correctly | Excluded; zero samples |
All eight invalid projects exited successfully without diagnostics. This is not a speed result or a confirmed canonical C++ selection. The existing Bun and Rust payload pins still verify locally. See the admission and current-profile report and raw evidence.
A per-pass global-reference index is now landed. Its frozen-parent A/B predates the separate transfer optimization:
| #850 candidate confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official CommonJS, 30 pairs | 26.271 ms | 25.519 ms | +0.084 to +0.898 ms |
| 1,024 families, 10 pairs | 375.040 ms | 324.106 ms | β10.883 to +86.004 ms; inconclusive |
| 4,096 families, 30 pairs | 3,505.488 ms | 3,064.615 ms | +377.701 to +575.922 ms |
The full family screen and adverse large-predicate observations remain in the version-scoped report. Its independent predicate recheck spans zero, not equivalence. Raw evidence retains 332 paired rounds; integration evidence verifies the combined source without timing it. Neither replaces the ranking above.
A borrowed resolver-key lookup was rejected despite eliminating allocations on repeated hits: independent latency confirmation was adverse.
| Rejected #851 confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official re-exports | 12.569 ms | 12.783 ms | β1.300 to β0.046 ms |
| CommonJS, 1,024 families | 291.316 ms | 293.459 ms | β12.614 to β0.817 ms |
| Re-exports, 4,096 leaves | 1,261.839 ms | 1,298.532 ms | β73.518 to β20.605 ms |
Production resolution is restored; the rebuilt native binary matches the accepted parent exactly. General ownership/condition controls remain. See the rejection report and all raw evidence.
A class/interface modifier-merge index is now landed under #853, preserving the complete original diagnostic scan on allocation failure:
| #853 exact-parent confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 29.197 ms | 29.176 ms | β0.086 to +0.566 ms; inconclusive |
| 512 JSDoc families, 30 pairs | 156.808 ms | 155.196 ms | +0.268 to +2.385 ms |
| Class hierarchy, 30 pairs | 23.198 ms | 22.970 ms | +0.074 to +0.447 ms |
| 8,192 families, five six-pair batches | 18,406.634 ms | 18,069.441 ms | +84.799 to +424.692 ms pooled; batch interval spans zero |
The ~1% confirmed smaller-scale/class gains do not establish universal speedups. All 442 paired rounds / 660 admissions, the adverse first large batch and inconclusive risk checks remain in the full report and raw evidence. The separate whole-file JSDoc class-owner scan is now indexed in a later, separately frozen #853 experiment:
| Class-local typedef owner confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 29.662 ms | 28.097 ms | +1.339 to +1.753 ms |
| 512 JSDoc families, 30 pairs | 157.129 ms | 131.756 ms | +23.146 to +33.404 ms |
| 8,192 families, five six-pair batches | 18,790.065 ms | 12,398.067 ms | +5,665.278 to +6,661.269 ms |
These medians are 5.3%, 16.1% and 34.0% lower; all 30 pairs per confirmation favor the candidate. The large five-batch interval is also positive. All 442 rounds / 660 admissions, including variable large observations and adverse-but-inconclusive predicate/re-export rechecks, remain in the full report and raw evidence. Neither Home-only A/B establishes a new five-compiler ranking or universal speedup. The fresh matrix above is separately measured with all 145 admissions and 3,000 samples. Current-source diagnostic-only early/middle stack samples now map another repeated nearest-prior value-declaration scan under #854; see the profile report.
That nearest-prior query is now indexed with syntax-only candidates and complete scalar fallback:
| #854 nearest-prior confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 29.169 ms | 28.265 ms | +0.568 to +1.000 ms |
| 512 families, 30 pairs | 147.003 ms | 132.509 ms | +6.169 to +19.478 ms |
| 8,192 families, five six-pair batches | 14,287.718 ms | 10,035.663 ms | +3,907.759 to +5,880.549 ms |
Confirmed medians are 3.1%, 9.9% and 29.8% lower; the large five-batch
interval is also positive. All 472 rounds / 660 admissions remain,
including the deep_types screen warning and inconclusive adverse rechecks.
See full tables and scope
and raw evidence.
The latest full competitor matrix above measures this landed source separately;
its ranking is not inferred from these Home-only A/Bs. A new diagnostic-only
profile identifies repeated virtual-section and require-binding work; see the
updated profile.
The measured virtual-section prefix scans are now indexed with complete raw source facts and scalar allocation-failure fallback:
| #854 virtual-section confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 27.475 ms | 27.284 ms | β0.791 to +0.576 ms; inconclusive |
| 512 families, 30 pairs | 119.253 ms | 114.483 ms | +2.752 to +5.372 ms |
| 8,192 families, five six-pair batches | 8,571.067 ms | 7,274.721 ms | +1,275.955 to +1,657.831 ms |
Scale medians are 4.0% and 15.1% lower; all 30 large pairs favor the candidate, with a positive five-batch interval too. All 502 rounds / 660 admissions remain. Deep-type/recursive-generics screen warnings are retained; recursive generics remains 1.5% slower in independent confirmation, with a nearly entirely negative interval spanning zero. This is not equivalence or a regression-free claim. See the full results and unresolved risks and raw evidence. The later full matrix above measures this landed source separately; its ranking is not inferred from the Home-only A/B. Current diagnostic-only samples map remaining require-binding and previous-JSDoc work in the new profile.
A later shared require-binding presence candidate was rejected despite scale gains because independent class-hierarchy confirmation regressed:
| Rejected #854 shared-presence confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 26.802 ms | 26.968 ms | β0.094 to +0.498 ms; inconclusive |
| 512 families, 30 pairs | 115.434 ms | 110.414 ms | +0.588 to +5.410 ms |
| 8,192 families, five six-pair batches | 7,577.868 ms | 6,487.183 ms | +958.507 to +1,789.384 ms |
| Class hierarchy, 30 pairs | 22.280 ms | 22.405 ms | β0.429 to β0.041 ms |
The full candidate was restored and never pushed to production. All 502
rounds / 660 admissions, including variable observations and inconclusive
carried risks, remain in the
rejection report
and raw evidence.
Current main includes later #846 correctness work; this Home-only rejection
does not refresh the earlier five-compiler ranking. Linux workflow dispatch
was refused because repository Actions are disabled; no new platform result
or C++ admission is claimed.
A distinct presence-only fact index was also rejected for confirmed interface-composition regression, despite independent target-scale gains:
| Rejected #854 presence-only confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 29.938 ms | 29.991 ms | β4.646 to +2.181 ms; inconclusive |
| 512 families, 30 pairs | 121.349 ms | 115.059 ms | +4.278 to +9.173 ms |
| 8,192 families, five six-pair batches | 8,050.697 ms | 6,637.805 ms | +918.689 to +1,822.483 ms |
| Interface composition, 30 pairs | 44.753 ms | 45.817 ms | β6.423 to β1.076 ms |
Source and native are restored; the candidate was never pushed. All 532 rounds / 660 admissions remain, including variable samples and unresolved warnings. See the full rejection report and raw evidence. No layout tweak or repeat-until-pass is used, and no new ranking is inferred.
The refreshed restored-source matrix above retains all 145 admissions / 3,000 samples with unchanged competitor pins. Current-source diagnostic-only samples now map a distinct previous-JSDoc ancestor-prefix fallback and repeated value resolution; see the new source/assembly profile. Sampling does not establish whole-run CPU percentages or a new optimization gain.
A distinct JSDoc ancestor-prefix index is now accepted under #854. Its exact-parent Home-only confirmation improves the 8,192-family median by 9.1%, with all 30 pairs faster across five batches. Smaller cases remain inconclusive, as do the independent declaration checks:
| #854 JSDoc ancestor-prefix confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 28.625 ms | 28.648 ms | -0.054 to +0.351 ms |
| 512 families, 30 pairs | 114.294 ms | 111.934 ms | -1.461 to +2.965 ms |
| 8,192 families, five six-pair batches | 7,712.274 ms | 7,007.293 ms | +622.101 to +730.809 ms |
| Class hierarchy, 30 pairs | 22.629 ms | 22.543 ms | -0.062 to +0.428 ms |
| Interface composition, 30 pairs | 33.850 ms | 33.772 ms | -0.373 to +0.200 ms |
All 532 rounds / 660 admissions remain. Recursive generics retains a slower independent median and nearly negative interval; no equivalence or regression-free claim is made. See the complete results and warnings and raw evidence. The five-compiler matrix above now measures the landed source separately; its ranking is not inferred from this Home-only A/B. Universal leadership, Zod admission and other-platform coverage remain incomplete. See the new matrix and full evidence.
The latest exact-native profile and audit samples the unchanged compiler after 31 complete admissions. Explicit native PCs identify two further statement scans; these are locations, not CPU shares:
| Native scan candidate | Early displayed offsets | Middle displayed offsets |
|---|---|---|
| Local namespace-import lookup (#857) | 188, 200 | 188, 200 |
| Function-signature collection | 36, 56 | 36, 96 |
Raw collapsed counts/ellipses and both stopped diagnostic-build attempts are retained. Earlier diagnostic profiles prove pre-link object-byte equality, not final native-executable equality. No diagnostic image is timed.
A later ordered namespace-import candidate under #857 was rejected for confirmed independent destructuring regression, despite target-scale gains:
| #857 namespace-import confirmation | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 26.820 ms | 26.733 ms | -0.117 to +0.761 ms |
| 512 families, 30 pairs | 113.317 ms | 110.763 ms | +1.166 to +3.012 ms |
| 8,192 families, five six-pair batches | 6,823.087 ms | 6,281.212 ms | +506.044 to +630.443 ms |
| Destructuring, independent 30 pairs | 13.908 ms | 14.030 ms | -0.237 to -0.029 ms |
| Class hierarchy, 30 pairs | 21.975 ms | 22.001 ms | -0.140 to +0.214 ms |
| Interface composition, 30 pairs | 32.604 ms | 32.529 ms | +0.002 to +0.373 ms |
The candidate was never pushed; source and native are restored. All 592 rounds / 660 admissions, warnings and shared-lock waits remain in the complete rejection report and raw evidence. No repeat-to-pass or alignment tuning is used; the separate five-compiler ranking above is not changed by this rejected Home-only A/B.
The shared function-statement candidate under #859 was also rejected: its supported scaling gain did not override independent predicate regression.
| #859 shared function groups | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 26.544 ms | 26.679 ms | -0.255 to +0.156 ms |
| 512 families, 30 pairs | 112.479 ms | 110.040 ms | +0.364 to +3.614 ms |
| 8,192 families, five six-pair batches | 7,295.837 ms | 6,566.492 ms | +616.393 to +1,052.243 ms |
| Large predicates, independent 30 pairs | 242.178 ms | 243.708 ms | -7.550 to -0.122 ms |
| Class hierarchy, 30 pairs | 23.109 ms | 22.770 ms | -0.029 to +0.331 ms |
| Interface composition, 30 pairs | 33.648 ms | 33.655 ms | -0.131 to +0.317 ms |
All 622 pairs / 660 admissions, five batches, adverse points and original validation/reconciliation evidence are retained. The candidate was never pushed; source and native are restored byte-for-byte. See the complete rejection report and raw evidence. Inconclusive intervals do not establish equivalence; the separate competitor ranking above is unchanged by this rejected Home-only A/B.
The stateless value-name guard under #861 is not admitted: interruption lost one batch's execution record and the fifth batch stopped at the disk floor. Retained observations include:
| #861 retained measurement | Parent | Candidate | Paired mean-saving 95% interval |
|---|---|---|---|
| Official checked JS, 30 pairs | 36.102 ms | 37.224 ms | -4.705 to +1.400 ms |
| 512 families, 30 pairs | 147.629 ms | 149.565 ms | -3.734 to +2.916 ms |
| Interface family screen, 10 pairs | 47.791 ms | 60.971 ms | -17.033 to -4.314 ms |
| Interface independent recheck, 30 pairs | 52.294 ms | 50.145 ms | -13.029 to +7.541 ms |
| Interface separate declaration check, 30 pairs | 55.683 ms | 62.015 ms | -15.476 to +23.459 ms |
| 8,192 families, third batch data only | 14,264.008 ms | 15,088.627 ms | -15,472.494 to +8,329.141 ms |
| 8,192 families, fifth batch disk-stopped | No completed pairs | No completed pairs | Not available |
All 706 of 712 planned pairs / 660 admissions are retained, including 24 of 30 planned large pairs. The candidate was never pushed; source and native are restored. See the complete unadmitted report and raw evidence. No timings were repeated or excluded. Incomplete execution and zero-spanning intervals do not establish improvement or equivalence; competitor ranks stay unchanged.
Imported Record/indexed-interface fixes are now landed. Their diagnostic results below are untimed admission checks; the separate matrix above times the landed compiler:
| Admission check | Result | Remaining limitation |
|---|---|---|
| Existing five-compiler benchmark protocol | 145/145 checks pass | No new timing samples |
| Later protocol-5 null-safe contract | 150/150 untimed checks pass | Existing matrix remains protocol 4 |
| String, number, symbol and mixed Record domains | Silent positives; exact negative errors | Finite and symbolic keys remain incomplete |
| Imported indexed literals and return types | Silent positive; three exact negative errors | General fixtures, not all TypeScript programs |
| Complete pinned Zod 4.5.2 graph | 241 TS errors and two HM9002 warnings | Not admitted; zero timing samples |
The clean parent reported 195 TS errors and three HM9002 warnings on Zod; the wider exact type graph exposes additional failures, so this is not a diagnostic-count improvement. See the admission report and raw evidence. The timing matrix above measures the landed source separately; these diagnostic checks do not establish a causal speedup.
The timing tables were measured with the standalone compiler build
(zig build home-tsc). home tsc runs the same compiler from inside the full
home binary, which adds some process-startup cost that has not been
benchmarked yet. Expect it to show mostly in the startup row.
How the benchmark stays fair. Every compiler gets the same generated
strict project in its canonical check-only mode: --noEmit -p <same tsconfig.json>
for tsc/native TS 7/Home/Rust, and bun check --no-pretty --all in that same
project directory. Before any
timing, each compiler must accept the valid project cleanly, and on workloads
with negative controls it must also reject planted type errors with exactly
the expected diagnostic codes, so no compiler can win by skipping work. Compiler order rotates every round, all samples are
kept, and compiler versions are pinned and hash-checked. Projects use noLib
so the numbers compare checker work rather than bundled standard-library size.
These are synthetic workloads on local machines, not a promise about every
project. Reproduce them yourself:
./pantry/.bin/zig build home-tsc -Doptimize=ReleaseFast
./bench/vs_tsgo/run.sh setup && ./bench/vs_tsgo/run.sh corpus
# Install the verified native payloads described in bench/vs_tsgo/profiles/README.md.
./bench/vs_tsgo/run.sh cold --runs 30 --warmup 3 \
--competitor-manifest bench/vs_tsgo/profiles/darwin-arm64.json
./bench/vs_tsgo/run.sh report
./bench/vs_tsgo/run.sh evidenceThe raw evidence archive
contains all 600 byte-for-byte Hyperfine round files (3,000 samples), 140
admission records, normalized metadata, and checksums. Its SHA-256 is
ed253feb8650bcb68995ba7c21ad83c07c2ed6652fc4747a879c00f35c60c8fd.
| Gate | Frozen input | Current Home result | Regression policy |
|---|---|---|---|
| Full Zod graph | Zod 4.5.2, 106 production .ts files |
196 TypeScript diagnostics (tsc: 0) |
Every diagnostic reduction is checked against the unchanged graph |
Checker-synthesized any provenance |
Same byte-pinned Zod archive | 3 HM9002 | CI fails if the count exceeds the reviewed ceiling of 3 |
| Zod core proxy | Zod 4.5.2, 21 production .ts files |
0 Home-only diagnostics; 1 shared proxy-boundary TS2307 | No Home-only identity may be added |
The separate restored-source audit for #751 compares the exact historical parent and fix with all locales restored:
| Historical Zod 4.5.2 gate | Parent diagnostics / identities | #751 diagnostics / identities | Added identities |
|---|---|---|---|
| Core roots | 146 / 141 | 146 / 141 | 0 |
| Locale roots | 145 / 140 | 145 / 140 | 0 |
Both pinned TypeScript engines accept these projects with zero diagnostics; this correctness check is untimed and does not change the current-source rows.
The provenance row currently covers expression-stack exhaustion, invalid
TypeScript and checked-JS catch-annotation recovery, TS7009 implicit-constructor
recovery, TS2350/TS2351/TS2679 invalid-new recovery, TS2538 invalid index-type recovery, TS7015 numeric-index mismatch recovery, TS7017 global-this index
recovery, TS7052/TS7053 implicit element-access recovery, TS7057 implicit-yield-result recovery, TS2683 implicit-this
recovery, TS1339/TS1340 import-namespace recovery, TS1361/TS1362 type-only value-use recovery, TS18046/TS2571 unknown-object recovery, TS2304/TS2552 unresolved-value recovery, TS2331/TS2332 invalid-this expression recovery, TS2348/TS2349 invalid-call recovery, TS2558 JSX class type-argument arity recovery, TS2698 invalid object-spread recovery, TS2749 value-used-as-type recovery, TS6234 getter-call recovery, diagnosed
TS2693 typeof type-only recovery, TS2694 CommonJS import-member recovery, TS2708 namespace-as-value recovery, TS2314 built-in-Array and checked-JSDoc generic-arity recovery, TS2304 uppercase-nullish generic-argument recovery, TS2304 unresolved bare/parameterized and inaccessible cross-file generic-type recovery, TS2503/TS2833/TS2702/TS2713/TS2339/TS2694 unresolved qualified-type recovery, TS2307/TS2792 missing import-type module recovery, TS2795 invalid intrinsic-alias recovery, TS2304/TS2552 excluded-DOM Element/Document type recovery, TS2304/TS2583/TS2584 unavailable-library value recovery, TS2304/TS2583 unavailable Generator/AsyncGenerator type recovery, TS18013/TS18016 ECMAScript-private-member recovery, inherited static-private TS2339 recovery, direct-never TS2339 recovery including TS18031/TS18032 intersection reduction, TS2335/TS2337/TS17005 invalid-super() recovery, diagnosed invalid-super property recovery (TS2335/TS2336/TS17011/TS2340/TS2466/TS2659/TS2660), TS2815 illegal class-arguments recovery, TS2550/TS2551/TS2576/TS2812 specialized missing-member recovery, TS2304/TS2552 unresolved-typeof recovery (including reserved function), TS2339 missing indexed-type recovery on typeof globalThis, TS2331/TS2332/TS2465/TS2683/TS2816 typeof this recovery, plus TS2589, TS2590, and TS2799
recursion/representation recoveries; it is a correctness ratchet, not a claim
that every internal fallback has already been classified.
The current Zod count comprises only the reviewed trio of TS2698-linked
object-spread recoveries in classic/schemas.ts (two sites) and
classic/from-json-schema.ts (one site). The four direct-never TS2339
recoveries previously visible at lines 649, 670 twice, and 671 are eliminated
by the source-independent negative-typeof and chained-discriminant flow fix
tracked in #835, without
suppressing diagnostics or widening legitimate never values. The pinned
production graph contains no yield expressions, so adding TS7057 provenance
contributes no Zod sites; the TS18013 private-access migration likewise leaves
the reviewed count unchanged.
The archive SHA-512, project shape, and maximum count are enforced by
scripts/ts-unmodeled-any-ratchet.py.
See the TypeScript parity plan for migration
status and TypeScript performance for the full
real-project audit history.
Local replacement qualification tracks
the remaining command, graph, output and wrapper gates across the local project
tree. Its inventory is discovery evidence; it does not establish that every
project can already replace tsc.
- Real-world graphs still surface false positives. The conformance corpus
is saturated, but large library graphs exercise interactions it doesn't.
The frozen full Zod graph above still has 196 Home diagnostics while
tschas zero; the smaller core proxy is clean of Home-only identities but is not a substitute for full-graph parity. Each fix is tracked in TypeScript performance. - No tagged release yet.
home tscships inside thehomebinary from the firstv*release on. Until then, buildhomefrom source (see Build from source). - Editor re-checks follow imports.
home lsprecompiles an edited TypeScript or JavaScript file and its transitive importers, then republishes diagnostics for affected open documents, including empty results that clear errors after an unsaved dependency edit. Files changed only on disk still need an editor notification or a fresh check.
More: TypeScript compiler, TypeScript parity by feature, editor and CLI tooling, TypeScript migration.
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.
macOS (Intel + Apple Silicon), Linux (x64 + arm64), and Windows (x64 + arm64,
via Git Bash / WSL) are supported.
Environment variables: HOME_VERSION pins a release tag (default latest),
HOME_INSTALL_DIR overrides the install location (default ~/.home), and
HOME_BIN_DIR overrides where the binary is placed.
// hello.home
fn main() {
print("Hello, Home!")
}
home build hello.home # native executable, nothing to install beside it
./hello # Hello, Home!
home run hello.home # or run it directly
home check hello.home # type-check without buildingSource files use the .home extension, or .hm for short. The
getting started guide walks
through a first project.
- Native binaries, no collector. Ownership and borrowing settle lifetimes at compile time β no pauses, no runtime shipped beside the binary. (memory model)
- One toolchain for two languages. The same compiler builds
.homefiles and type-checks TypeScript, so a mixed codebase needs one tool instead of two. (how it works) - Exhaustive pattern matching. A missing branch is a compile error, not a runtime surprise. (pattern matching)
- Compile time is just code.
comptimeruns real Home during compilation. (comptime) - Errors as values.
Resulttypes with?propagation, plus null-safety operators (?.,?:,??,?[]). (error handling) - Batteries in the stdlib. HTTP, database, JSON, async and FFI, with experimental threading π§. (standard library, threading status)
A condensed pass over the syntax. Each section links to the full page in the language guide.
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 (counter > 5) {
print("big")
} else {
print("small")
}
for (item in items) { print(item) }
for (i in 0..10) { print(i) }
for (index, item in items) { print("{index}: {item}") }
while (counter < 10) { counter = counter + 1 }
Strings interpolate with {}, ranges come with .len(), .step(),
.contains() and .to_array(), and arithmetic includes ** (power) and ~/
(truncating integer division). Full reference:
variables and
control flow.
fn add(a: int, b: int): int {
return a + b
}
fn greet(name: string = "World") { // default parameters
print("Hello, {name}!")
}
fn fetch_data(): async Result<Data> {
let response = await http.get("/api/data")
return response.json()
}
struct User {
id: i64
name: string
}
enum Color {
Red,
Green,
Custom(r: int, g: int, b: int)
}
let user = User { id: 1, name: "Alice" }
match color {
Color.Red => print("red"),
Color.Green => print("green"),
Color.Custom(r, g, b) => print("rgb({r}, {g}, {b})")
}
if and match are expressions, so they return values:
let status = if (code == 200) { "ok" } else { "error" }
let label = match x {
1 => "one",
2 => "two",
_ => "other"
}
More: structs and enums, pattern matching, traits.
let name = user?.name ?: "Anonymous" // elvis
let city = user?.address?.city // safe navigation
let first = items?[0] // safe indexing
fn read_file(path: string): Result<string, Error> {
let file = fs.open(path)? // ? propagates errors
return Ok(file.read_all())
}
match read_file("config.home") {
Ok(content) => process(content),
Err(e) => print("Failed: {e}")
}
More: type system, error handling.
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
More: generics, comptime, macros, FFI.
import http { Server, Response }
fn main() {
let server = Server.bind(":3000")
server.get("/users/:id", fn(req): Response {
let id = req.param("id")
return Response.json({ id: id })
})
server.listen()
}
More: standard library, web services.
Conservative on purpose: anything not exercised by an example or a test stays "maturing" even when the underlying code is largely there.
| Area | Status | Detail |
|---|---|---|
| Lexer, parser, type inference | Usable today | Capability matrix |
TypeScript front end (home tsc) |
Usable today; lowest median on 1 / 20 admitted workloads in the 2026-10-10 matrix; faster than native TS7 on 13 / 20 | TypeScript performance |
| TypeScript conformance (byte-exact) | Previous pass counts withdrawn; honest corpus revalidation in progress | TypeScript parity |
Promise chain and readonly Promise.all inference |
Exact TS2322 controls; 4,410 / 4,410 checker tests | Untimed validation |
| TypeScript diagnostic codes emitted | 1,620 / 2,079; 0 reachable targets left | Diagnostic reachability |
Language-server methods routed (home lsp, TypeScript and .home) |
76 / ~80 | Parity status |
| Native codegen | π§ Home ASTβnative is maturing; JS/TS standalones run bundled graphs in JSC, not TSβnative lowering | Codegen tests Β· standalone tests |
| Bun runtime port | 552 / 1,193 files integrated | Bun parity |
node:* modules JS-callable |
24 / 47 (partial surfaces) | Node.js parity |
| Compiler test suite | ~8,415 tests | Parity status |
Every figure is a file-count, row-count or byte-for-byte measurement against an
external baseline, refreshed with scripts/measure-parity.sh. The full
breakdown β headline numbers, per-phase runtime port, LSP method list,
frontend performance snapshots β lives in
Parity status.
Requires the Pantry-pinned Zig 0.17 dev toolchain; nothing is installed globally.
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 it
./zig-out/bin/home build examples/fibonacci.home
./examples/fibonacciCommon commands:
| Command | What it does |
|---|---|
./pantry/.bin/zig build |
Build the compiler |
./pantry/.bin/zig build home-tsc -Doptimize=ReleaseFast |
Build the standalone tsc benchmark binary (users run home tsc) |
./pantry/.bin/zig build test |
Run the unit-test suite |
./pantry/.bin/zig build examples |
Run the native example executables |
./pantry/.bin/zig build run -- examples/fibonacci.home |
Build, then run a file |
scripts/check-examples.sh |
home check every .home example |
scripts/measure-parity.sh --diff |
Fail if the published parity numbers drifted |
home/
βββ src/main.zig # CLI entry point
βββ packages/ # 130+ Zig packages, each with its own tests
β βββ lexer/ parser/ ast/ types/ codegen/ interpreter/
β βββ ts_lexer/ ts_parser/ ts_checker/ ts_emit/ ts_program/
β βββ ts_lsp/ ts_lsp_server/ ts_conformance/ ts_resolver/
β βββ hir/ binder/ diagnostics/ compat/ runtime/
β βββ ... # http, database, async, ffi, graphics, β¦
βββ docs/ # Documentation site (home-lang.org)
βββ examples/ # Example programs
βββ tests/ # Integration tests
βββ stdlib/ # Standard library
Monorepo structure and architecture go deeper.
Contributions welcome β see CONTRIBUTING.md. Release notes live in CHANGELOG.md.
MIT β see LICENSE.
