Skip to content

idyllic-labs/typemojo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TypeMojo

TypeMojo is a Mojo-to-TypeScript transpiler for people who want more than a parser demo.

It takes a large, practical subset of Mojo and lowers it to runnable ESM TypeScript with a real proof harness behind it: transpilation, strict typechecking, execution, audits, and a separate native-Mojo validation lane. It is not a full Mojo compiler, and it does not pretend otherwise.

Why This Repo Exists

Mojo has interesting language ideas. TypeScript has a huge tooling ecosystem. TypeMojo explores the overlap seriously:

  • Mojo syntax and structure as source language.
  • TypeScript, ts-morph, and compiler APIs as the target playground.
  • End-to-end examples as the source of truth, not aspirational feature lists.

The goal is not "compile everything." The goal is "transpile a meaningful subset well, honestly, and with proof."

Status

Lane Status What It Means
Transpiler corpus 100/100 green 100 runnable programs transpile, typecheck, and execute
Native Mojo lane 14/14 green Curated Mojo-native programs run under local mojo 24.4.0
Strict TS audit green Generated TypeScript has 0 strict diagnostics in the current audit
Broader Mojo compatibility tracked separately The full transpiler corpus is not claimed to be native-Mojo runnable

Current corpus breakdown:

  • 16 fixtures
  • 7 benchmarks
  • 77 TypeScript / compiler / ts-morph examples

Catalog source of truth:

Native Mojo source of truth:

What TypeMojo Is Good At

  • Lowering fn and def to typed TypeScript functions
  • Lowering struct to classes and trait to interfaces
  • Mapping Mojo containers onto JS-native targets: List[T] -> T[], Dict[K, V] -> Map<K, V], Set[T] -> Set<T>
  • Rewriting common built-ins and methods: print, len, range, zip, enumerate, append, items(), slicing, and string formatting
  • Handling async functions, generators, tuple unpacking, comprehensions, match, imports, and try/except
  • Emitting importable modules with guarded main() entrypoints
  • Exercising TS-native concepts through real examples: package imports, namespace imports, factory/printer APIs, ts-morph project traversal, checker queries, refactor previews

Where It Is Still Lossy

Some Mojo semantics do not have a faithful TS equivalent today. TypeMojo tracks those explicitly.

Current lossy areas include:

  • Ownership conventions like owned, borrowed, mut, ref, out, inout
  • Transfer expressions like value^
  • Marker traits like Copyable and Equatable
  • Compile-time parameters and compile-time call arguments
  • Anything with no implemented lowering path yet

This is not hidden behind silent degradation.

  • AnyType lowers to explicit UnsafeAny
  • strict mode rejects lossy transforms
  • the audit reports where unsafe interop still exists

That design is intentional, and closer to the AssemblyScript philosophy than to a "shrug and emit any" transpiler.

Quick Start

bun install

# Transpile one file to stdout
bun run src/cli.ts input.mojo

# Write output to a file
bun run src/cli.ts input.mojo -o output.ts

# Transpile a directory
bun run src/cli.ts tests/fixtures -o out/

# Validate only
bun run src/cli.ts input.mojo --check

# Full transpiler proof lane
bun run scripts/e2e.ts

# Strict generated-TS audit
bun run scripts/example-audit.ts

# Curated native Mojo lane
bun run scripts/mojo-e2e.ts

# Broader native compatibility report
bun run scripts/mojo-compat-report.ts

Example

Source:

@value
struct Point:
    var x: Float64
    var y: Float64

    fn distance(self) -> Float64:
        return sqrt(self.x ** 2 + self.y ** 2)

def main():
    var p = Point(3.0, 4.0)
    print(p.distance())

Output:

import { _print } from "./_typemojo_runtime";

export class Point {
  x!: number;
  y!: number;

  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }

  distance(): number {
    return Math.sqrt(this.x ** 2 + this.y ** 2);
  }
}

export function main() {
  const p = new Point(3.0, 4.0);
  _print(p.distance());
}

Proof, Not Vibes

TypeMojo is built around verification lanes, not optimistic docs.

1. Transpiler Lane

  • scripts/e2e.ts
  • Transpiles the full corpus
  • Typechecks generated TypeScript
  • Executes every runnable program

2. Strict TS Audit

3. Native Mojo Lane

  • scripts/mojo-e2e.ts
  • Runs the curated native-Mojo catalog
  • Enforces expected output
  • Intended to stay 100% green

4. Native Compatibility Report

  • scripts/mojo-compat-report.ts
  • Runs the broader fixtures and benchmarks under Mojo
  • Reports the gap honestly
  • Does not pretend the full TS-interop corpus should execute unchanged under native Mojo

That split matters. A repo like this gets worse when "native Mojo support" and "transpiler support" are mixed into one dishonest number.

AssemblyScript-Style Strictness

TypeMojo now has a dedicated typechecking environment for generated output:

This gives the generated TypeScript:

  • strict compiler settings
  • explicit ambient target types
  • no silent implicit-any leakage
  • visible unsafe boundaries via UnsafeAny

That is a better design than pretending JS/TS interop is always type-safe.

Example Waves

The 77 examples under examples/ are not filler. They are organized pressure tests for the lowering model.

Waves include:

  • TypeScript compiler API scans: diagnostics, import graphs, switch audits, template literals, AST printers, namespace scans, JSX inventories, type-node scans
  • Compiler API builders: enum emission, union builders, overload scanning, JSDoc analysis
  • ts-morph structural examples: project traversal, class/interface/export/import inventories, heritage graphs, overload matrices, reference search
  • ts-morph type-system examples: mapped types, conditional types, literal types, tuple types, recursive types, call signatures, ambient declarations
  • Refactor and symbol examples: rename previews, symbol maps, binding-pattern scans, import-usage maps

See:

CLI Commands

Common commands from package.json:

bun test
bun run scripts/e2e.ts
bun run scripts/example-audit.ts
bun run scripts/mojo-e2e.ts
bun run scripts/mojo-compat-report.ts
bun run scripts/bench.ts
bun run scripts/generate-tooling-examples.ts
bun run build

Architecture

Mojo source
  -> Lexer
  -> Parser
  -> Analyzer
  -> CodeGen
  -> ESM TypeScript

Key files:

Philosophy

Three rules drive the project:

  1. If a feature matters, it should appear in an executable example.
  2. If a transform is lossy, it should be visible and rejectable.
  3. If a number is quoted in the README, there should be a script that proves it.

That is the bar.

About

Mojo to TypeScript transpiler

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors