TypeScript <-> MoonBit bridge generator
moon update # fetch deps
moon check --deny-warn # build the library + cmd binaries
moon run src/cmd/ts2mbt -- --help # TS -> MoonBit
moon run src/cmd/mbt2ts -- --help # MoonBit -> 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.
moon run src/cmd/mbt2ts -- --input mizchi/foo --out dist
# TypeScript -> MoonBit. For bare npm-style inputs, the runtime module spec
# defaults to the input specifier.
moon run src/cmd/ts2mbt -- --input neverthrow --out dist
# File input also works; pass the runtime module when it differs from the
# declaration entry path.
moon run src/cmd/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.
moon run src/cmd/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>/.
moon run src/cmd/ts2mbt -- vendor hono
# Vendor everything in dependencies + devDependencies of ./package.json.
moon run src/cmd/ts2mbt -- syncsrc/
└── internal/
└── generated/
├── hono/
│ ├── bridge.mbti
│ ├── bridge.mbt
│ ├── bridge.js
│ ├── moon.pkg.json
│ ├── package.json # name = "@tsmbt-bridge/hono"
│ └── SCAFFOLD_DIAGNOSTICS.md
└── types__react/
└── ... (same shape, runtime spec defaults to `react`)
node_modules/
└── @tsmbt-bridge/
├── hono -> ../../src/internal/generated/hono
└── types__react -> ../../src/internal/generated/types__reactmoon run src/cmd/mbt2ts -- scaffold src/pkg.generated.mbti out/ts-pkg
# optional: rewrite external MoonBit package imports to publishable TS specifiers
moon run src/cmd/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
moon run src/cmd/mbt2ts -- facade-scaffold src/pkg.generated.mbti out/ts-pkg# only link.js.exports JSON
moon run src/cmd/mbt2ts -- link-config src/pkg.generated.mbti
# only recursive .d.ts package
moon run src/cmd/mbt2ts -- package src/pkg.generated.mbti out/ts-pkg
# single .d.ts from one .mbti file without recursive rewrite
moon run src/cmd/mbt2ts -- decl src/pkg.generated.mbtimoon run src/cmd/ts2mbt -- scaffold path/to/entry.d.ts /runtime/module.js out/moonbit-pkg# full bridge package
moon run src/cmd/ts2mbt -- package path/to/entry.d.ts /runtime/module.js out/moonbit-pkg
# inspect generated decl/ffi/bridge snippets without writing a package
moon run src/cmd/ts2mbt -- bridge path/to/entry.d.ts /runtime/module.js
moon run src/cmd/ts2mbt -- ffi path/to/entry.d.ts /runtime/module.js
moon run src/cmd/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) -> Boolasync 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_sync_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?) -> Bool