English | 简体中文
One runtime for TypeScript and Python.
Run either language. Import across both ecosystems. Ship one executable.
Poly is an experimental runtime and toolchain for applications that use both TypeScript and Python. Bun runs JavaScript and TypeScript, RustPython runs Python, and a Rust host brings them together in one executable and one OS process.
The goal is not to hide one language behind an RPC service. Both languages should be first-class parts of the same project, module graph, development workflow, and release artifact.
Important
Poly is still an engineering prototype. The shared runtime and low-level in-process bridge exist today; cross-language imports, unified dependency management, and application bundling are roadmap features.
Python files should behave like modules, not services:
import { add } from "./math_tools.py" with { type: "python" };
console.log(add(20, 22)); // 42Poly will also provide a built-in runtime module for cases that need explicit access to Python:
import { python } from "poly";The common project lifecycle should use one CLI:
poly run app.ts # run a TypeScript entry point
poly run tool.py # run a Python entry point
poly sync # resolve both ecosystems
poly build app.ts # produce a standalone application
poly run entry-point routing is part of the current prototype. Static
cross-language imports, poly sync, and poly build are not implemented yet.
A Poly project is designed to keep the native tools and metadata of both ecosystems:
my-app/
├── package.json # JavaScript and TypeScript dependencies
├── bun.lock
├── pyproject.toml # Python dependencies
├── uv.lock
├── poly.toml # entries, runtimes, and interop settings
└── src/
├── main.ts
└── model.py
| Layer | Direction |
|---|---|
| Runtime | Bun and embedded RustPython in one executable |
| Modules | Direct imports across TypeScript and Python |
| Dependencies | Bun for npm packages, uv for Python resolution and locking |
| Build | Collect both module graphs, dependencies, and resources |
| Distribution | One platform-native executable with no Python sidecar |
Poly owns the compatibility boundary. In particular, uv is used for dependency resolution and materialization, but RustPython is not an officially supported uv interpreter and cannot load arbitrary CPython native wheels. Poly therefore needs its own compatibility checks and reports.
The current M0 prototype integrates RustPython directly into a pinned Bun source tree:
poly executable
│
├── Bun / JavaScriptCore
│ ├── JavaScript and TypeScript entry points
│ └── Bun.polyPythonCall()
│
├── Rust host bridge
│ └── JSON value and error envelope
│
└── RustPython
├── Python entry points
└── frozen Python standard library
The current TypeScript-to-Python call path stays on the Bun/JSC caller thread. It does not start a subprocess, sidecar, worker thread, socket, or stdio RPC channel. Python execution is synchronous and blocks the Bun event loop.
This JSON bridge is a bootstrap layer. It proves that both runtimes can coexist inside the same process while keeping their garbage-collected objects separate. The roadmap replaces this low-level interface with imports, callable proxies, tagged values, and explicit lifetime semantics.
| Capability | Status |
|---|---|
| Bun and RustPython source integration | Implemented |
.js / .ts and .py entry-point routing |
Validated in a Windows Release build |
| TypeScript → Python JSON bridge | Validated through the linked JSC and RustPython runtimes |
| Python module cache and reload semantics | Planned |
| Static cross-language imports and callable proxies | Planned |
| Cooperative async execution | Planned |
poly sync with uv compatibility checks |
Planned |
poly build standalone applications |
Planned |
See the validation record for the exact verified boundary and the roadmap for planned work.
This is the fastest check and does not compile Bun:
cargo test -p poly_pythonIt initializes RustPython on one caller thread, invokes
poly/examples/math_tools.py::add(20, 22), verifies the return value, and
checks stdout capture. It does not produce the final poly executable.
A full build compiles the checked-out fork directly. The repository already contains Bun's source and history; the build does not clone another Bun worktree or apply a downstream patch. Expect roughly 10 GB of disk usage and a 10–30 minute build.
Prerequisites include Git, PowerShell 7, Bun 1.3.2, Rust, and Bun's native build toolchain. See the Bun integration workflow for the complete Windows and Linux environments.
The fork was established from Bun commit
e7ddfeb19e8bc714f6137aa2b1cd5a7bb56b93d7
and receives later upstream changes through explicit merge commits.
.\poly\scripts\build.ps1 -Configuration Release
.\dist\poly.exe poly\examples\python_main.py -- first second
.\dist\poly.exe poly\examples\main.tspwsh ./poly/scripts/build.ps1 -Configuration Release
./dist/poly poly/examples/python_main.py -- first second
./dist/poly poly/examples/main.tsOmitting -Configuration Release produces a Debug build.
The TypeScript example currently uses the transitional low-level SDK in
poly/examples/main.ts. It is an integration fixture,
not the intended final developer experience.
src/ Bun runtime plus the in-tree Poly integration
src/poly_python/ RustPython embedding and call bridge
poly/scripts/build.ps1 Direct fork build entry point
poly/sdk/ Transitional low-level TypeScript SDK
poly/examples/ TypeScript and Python integration examples
poly/docs/ Design, roadmap, and validation records
poly/poly.toml Future Poly project manifest
Clones of this repository can configure Bun as the upstream remote and merge it normally:
git remote add upstream https://github.com/oven-sh/bun.git
git fetch upstream
git merge upstream/mainThe first unrelated-history merge is already part of main; future syncs do
not use --allow-unrelated-histories and do not regenerate a Poly patch.
- Technical design
- Implementation roadmap
- Validation record
- Reproducible build and binary release plan
The linked design documents are currently written in Chinese.
The project website is published at
liooil.github.io/poly. Its source lives in
poly/website/, and changes on main are deployed through the
GitHub Pages workflow.
CIruns the RustPython bridge tests on Linux, macOS, and Windows. It also checks formatting, Clippy, the TypeScript fixture, the no-subprocess boundary, and direct source integration.Bun integration buildbuilds Windows x64 and Linux x64 executables for relevant pull requests or manual runs, then exercises both language entry points and the TypeScript-to-Python path.Releaseaccepts onlyv*tags and publishes assets only after both platform builds and smoke tests succeed.
Code original to this project is available under the MIT License.
The final poly executable also contains Bun, JavaScriptCore/WebKit,
RustPython, and other third-party components under their respective licenses.
See THIRD_PARTY_NOTICES.md for the preliminary
inventory and release requirements.
Tagged releases are intended to be built by GitHub Actions and distributed as GitHub Release assets with build metadata and checksums.