TypeScript <-> MoonBit bridge generator
Dependencies
moon install mizchi/ts/cmd/ts2mbt # TS -> MoonBit (generate / vendor / scaffold)
moon install mizchi/ts/cmd/mbt2ts # MoonBit -> TS (decl / scaffold / facade-scaffold)
# Or install both binaries in one go
moon install mizchi/ts/...# MoonBit -> TypeScript. Run `moon info` first so pkg.generated.mbti exists.
# This creates temporary MoonBit glue code, runs `moon build --target js`,
# and emits a TypeScript package backed by the built JS output.
mbt2ts --input mizchi/foo --out dist
# TypeScript -> MoonBit. For bare npm-style inputs, the runtime module spec
# defaults to the input specifier.
ts2mbt --input neverthrow --out dist
# File input also works; pass the runtime module when it differs from the
# declaration entry path.
ts2mbt --input path/to/entry.d.ts --module-spec /runtime/module.js --out dist
# Diagnostics can be redirected. Strict mode fails when unsupported exports,
# omitted MoonBit autolink members, or unbudgeted TS JSValue fallbacks are found.
ts2mbt --input neverthrow --out dist --diagnostics dist/diagnostics.md --strict# Vendor one npm package: resolve its types via node_modules and write a
# bridge sub-package under <moon-source>/internal/generated/<safe>/.
ts2mbt vendor hono
# Vendor everything in dependencies + devDependencies of ./package.json.
ts2mbt generatesrc/
└── internal/
└── generated/
├── hono/
│ ├── bridge.mbti
│ ├── bridge.mbt
│ ├── bridge.js
│ ├── moon.pkg
│ ├── package.json # type=module + self-contained imports
│ └── SCAFFOLD_DIAGNOSTICS.md
└── types__react/
└── ... (same shape, runtime spec defaults to `react`){
"dependencies": {
"@tsmbt-bridge/hono": "file:./src/internal/generated/hono"
}
}import {
"yourname/yourmod/internal/generated/hono" @hono,
}
options(
"is-main": true,
)mbt2ts scaffold src/pkg.generated.mbti out/ts-pkg
# optional: rewrite external MoonBit package imports to publishable TS specifiers
mbt2ts scaffold src/pkg.generated.mbti out/ts-pkg import-rewrites.json
# opt-in: also emit top-level MoonBit wrappers for omitted local methods/constructors
mbt2ts facade-scaffold src/pkg.generated.mbti out/ts-pkg# only link.js.exports JSON
mbt2ts link-config src/pkg.generated.mbti
# only recursive .d.ts package
mbt2ts package src/pkg.generated.mbti out/ts-pkg
# single .d.ts from one .mbti file without recursive rewrite
mbt2ts decl src/pkg.generated.mbtits2mbt scaffold path/to/entry.d.ts /runtime/module.js out/moonbit-pkg# full bridge package
ts2mbt package path/to/entry.d.ts /runtime/module.js out/moonbit-pkg
# inspect generated decl/ffi/bridge snippets without writing a package
ts2mbt bridge path/to/entry.d.ts /runtime/module.js
ts2mbt ffi path/to/entry.d.ts /runtime/module.js
ts2mbt decl path/to/entry.d.ts// TypeScript -> MoonBit: supported declaration shapes
export interface User {
readonly id: string;
name?: string;
}
export type UserPatch = Partial<Pick<User, "name">>;
export declare function parseUser(input: string): User;
export declare function listUsers(): Promise<User[]>;// MoonBit -> TypeScript: supported JS-exportable public surface
pub struct User {
id : String
name : String?
}
pub fn parse_user(input : String) -> User {
{ id: input, name: None }
}
pub async fn list_users() -> Array[User] {
[]
}# Check for errors
moon check --deny-warn
# Run tests
moon test --target native
# Verify high-level scaffold commands end-to-end
just verify-scaffolds
# Fixture-backed bridge quality report
just bridge-quality
# Optional local real-world probes
just verify-realworld-typescript
just verify-realworld-moonbit
# Format code
moon fmtlet CLI_VERSION : Stringfn cli_bail(message : String) -> Unitfn cli_clean_error(message : String) -> Stringfn cli_exit(code : Int) -> Unitfn cli_fail(binary_name : String) -> Unitfn cli_parse_subcommand_args(args : Array[String], start : Int, min_args : Int, usage : String, help_hint? : String) -> CliArgScanfn cli_print_version(binary_name : String) -> Unitfn cli_subcommand_is_help(token : String) -> Boolfn cli_token_is_version(token : String) -> Boolfn compute_vendor_root(module_root : String, moon_mod_source : String) -> Stringasync fn emit_js_link_config_from_mbti(file_path : String, output_path : String?) -> Boolasync fn emit_moonbit_bridge(file_path : String, module_spec : String, decl_output_path : String?, ffi_output_path : String?, bridge_output_path : String?) -> Boolasync fn emit_moonbit_bridge_package(file_path : String, module_spec : String, output_dir : String, bare_module_specifier? : String?) -> Boolasync fn emit_moonbit_decl(file_path : String, output_path : String?) -> Boolasync fn emit_moonbit_js_ffi(file_path : String, module_spec : String, ffi_output_path : String?, bridge_output_path : String?) -> Boolasync fn emit_moonbit_scaffold_from_ts(file_path : String, module_spec : String, output_dir : String, write_diagnostics? : Bool, bare_module_specifier? : String?) -> Boolasync fn emit_typescript_decl(file_path : String, output_path : String?) -> Boolasync fn emit_typescript_decl_from_mbti(file_path : String, output_path : String?) -> Boolasync fn emit_typescript_facade_scaffold_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Boolasync fn emit_typescript_package_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Boolasync fn emit_typescript_scaffold_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Boolasync fn run_mbt_to_ts_unified_cli(args : Array[String], start : Int, print_help~ : () -> Unit) -> Boolasync fn run_ts_to_mbt_unified_cli(args : Array[String], start : Int, print_help~ : () -> Unit) -> Boolasync fn ts2mbt_generate_from_package_json(package_json_path_override? : String?, vendor_root_override? : String?) -> Boolasync fn ts2mbt_vendor_package(pkg_spec : String, module_spec_override? : String?, vendor_root_override? : String?, print_import_hint? : Bool) -> BoolTypeScript <-> MoonBit bridge generator
Dependencies