⚠️ Warning: This project is not yet stable and may undergo significant changes before reaching version 1.0.0. We strongly advise against using it in production environments.
TypeScript ergonomics, Rust performance, compiled to native. A typed, TypeScript-flavored language (
.ts) that compiles to native binaries via idiomatic Rust (wasm/napioutputs planned). Write TypeScript-flavored code, reuseoxcfor parsing, withds check/ds fmtbuilt on its AST in-process,ds build/ds runcaching builds in-project, dependencies declared in apackage.jsonthat lowers toCargo.toml, and type hints for any Rust crate drawn straight from its source.
| Package | Version | Description |
|---|---|---|
| dashscript | The ds toolchain in one package — translates oxc AST → Rust, package.json → Cargo.toml, bindgen, CLI, editor types. |
# one package — provides the `ds` command
$ pnpm add -g dashscript
# or as a standalone binary
$ cargo install dashscriptNo separate Rust install. DashScript manages its own pinned Rust toolchain — downloaded on first use like an npm dependency — so
pnpm add dashscriptis all you need.
// main.ts — TypeScript-flavored source
function greet(name: string): string {
return `Hello, ${name}!`;
}
const message: string = greet("DashScript");$ ds main.ts # run a file directly (like `node a.js`)
$ ds build main.ts # → dist/<name> — a native binary (default)
$ ds build main.ts --target rust # → dist/<name>/ — the translated Rust crateds main.ts runs a .ts file directly — translate → compile (cached) → run, like node a.js. ds build parses the .ts file with oxc, translates the AST to idiomatic Rust, then compiles it with cargo and ships a native binary in dist/<name> — the way vp pack ships a runnable artifact, not an intermediate project. Pass --target rust to stop at the translated Rust crate instead:
// generated by DashScript (--target rust)
fn greet(name: &str) -> String {
format!("Hello, {name}!")
}
fn main() {
let message: String = greet("DashScript");
}$ ds run <script> # run a package.json script (like `pnpm run`)ds run runs a shell command from package.json scripts ("start": "ds main.ts", "test": "cargo test", …) through the system shell, like pnpm run. (ds run is always explicit — running a file is ds <file.ts>.)
DashScript projects use a package.json — the one manifest every JS tool already reads. Standard npm fields map straight to cargo: bin (package.json bin → cargo [[bin]]) declares a project's executables, so one project compiles to several binaries; main → [lib]; Rust crate deps under dashscript.cargo.dependencies → [dependencies] (npm dependencies stay JS deps and never reach Cargo.toml); dashscript.cargo.devDependencies → [dev-dependencies]. On ds build, the package is translated into a Cargo.toml:
{
"name": "my-app",
"bin": {
"serve": "serve.ts",
"migrate": "migrate.ts"
},
"dashscript": {
"target": "bin",
"cargo": {
"dependencies": {
"serde": "1.0",
"tokio": "1.0"
}
}
}
}# fetch the crate — no .d.ts stub; types come straight from the crate source
$ ds add cargo:serdeds add cargo:<crate> fetches the crate via cargo and records it in package.json, but generates no .d.ts stub — Rust is statically typed, so the crate's own source (in ~/.cargo) is the complete type truth, read directly by the editor the way rust-analyzer reads its deps. For a local Rust file, ds add <file>.rs runs bindgen to emit a .d.ts declaration beside it. There is no separate ds gen step.
A .ts source is parsed with oxc_parser. ds check is the composite — translatability plus a format check, the way vp check lints + checks formatting; ds lint checks translatability alone; ds fmt formats in place. With no argument each runs over every .ts in the project (like vp check / oxlint), and ds check --fix writes the formatting fix instead of just reporting it. All built in-process on the parsed AST (no external oxlint/oxfmt dependency):
$ ds check # lint + format check, whole project (like `vp check`)
$ ds check --fix # ...and write formatting fixes
$ ds lint # translatability check only
$ ds fmt # format every .ts in placeThe emitted Rust is finally verified with cargo check / cargo clippy on the generated project.
DashScript maps a TypeScript-flavored surface to Rust semantics, growing incrementally as real demand drives each mapping — never speculatively.
- Language coverage — the full Rust type/memory-safety model (ownership, borrowing, lifetimes, traits), with TypeScript as the presentation only. Today: a safe TS→Rust subset (auto clone/borrow/narrowing bridge the gaps).
- Standard libraries — ES built-ins (
Math/String/Array/Object/Number, …), then thenode:stdlib (node:crypto,node:zlib,node:fs, …) and Web APIs (fetch, DOM, …). - Compatibility — degrade, don't reject — a construct the static translator can't lower runs under an embedded QuickJS engine at the function granularity (inheriting full ECMAScript semantics) instead of failing, so existing TS/JS keeps working without a rewrite. This is also DashScript's path to WinterTC (Ecma TC55) — the Minimum Common Web Platform API shared by Node, Deno, Bun, and Cloudflare Workers: the ECMAScript core via the engine, the Web APIs via Rust crates.
- More outputs —
wasmandnapitargets (Rust compiled to WebAssembly / napi-rs), so.tsships to the web and Node ecosystems. - Developer experience —
ds test, editor/LSP integration, conformance fixtures. - Self-hosting (north star) — rewrite the toolchain in
.tsitself, reachingoxc(and any Rust crate) through bindgen.
- Node.js 18.x or higher
- pnpm 9.x or higher (recommended package manager)
- Rust — managed by DashScript (a pinned toolchain is downloaded on demand); no separate install needed to use DashScript
- Git for version control
-
Clone the repository:
git clone https://github.com/DemoMacro/dashscript.git cd dashscript -
Install dependencies:
pnpm install
-
Build all packages:
pnpm build
pnpm build # Build all packages
cd packages/<pkg> && pnpm build # Build one package
vp check # Lint & formatWe welcome contributions! See CONTRIBUTING.md for the full contribution workflow, coding standards, and PR checklist.
This project is licensed under the MIT License - see the LICENSE file for details.
Built with ❤️ by Demo Macro