TypeScript wrapper for Python libraries with full type safety.
⚠️ Experimental Software (v0.2.0) - APIs may change between versions. Not recommended for production use until v1.0.0.
- Full Type Safety - TypeScript definitions generated from Python source analysis
- Multi-Runtime - Node.js (subprocess) and browsers (Pyodide)
- Rich Data Types - numpy, pandas, scipy, torch, sklearn, and stdlib types
- Efficient Serialization - Apache Arrow binary format with JSON fallback
-
Node.js 20+ (or Bun 1.1+ / Deno 1.46+)
-
Python 3.10+ with
tywrap-ir:pip install tywrap-ir
npm install tywrap
pip install tywrap-ir # Python component for code generation
npx tywrap init # Create config (and package.json scripts if present)
npx tywrap generate # Generate wrappersFor CI (or to verify a dependency upgrade didn’t change the generated surface):
npx tywrap generate --checkimport { NodeBridge } from 'tywrap/node';
import { setRuntimeBridge } from 'tywrap/runtime';
import * as math from './generated/math.generated.js';
const bridge = new NodeBridge({ pythonPath: 'python3' });
setRuntimeBridge(bridge);
const result = await math.sqrt(16); // 4import { NodeBridge } from 'tywrap/node';
const bridge = new NodeBridge({
pythonPath: 'python3',
virtualEnv: './venv',
timeoutMs: 30000
});NodeBridge is the default, correctness-first bridge. OptimizedNodeBridge is a performance-focused
prototype (process pooling + optional caching) and is not a drop-in replacement yet. See
ROADMAP.md for the unification plan.
Both bridges share a common JSONL core for protocol validation and timeouts.
By default, NodeBridge inherits only PATH/PYTHON*/TYWRAP_* from process.env to keep
the subprocess environment minimal. Set inheritProcessEnv: true if you need the
full environment. Large JSONL responses are capped by maxLineLength (defaults to
TYWRAP_CODEC_MAX_BYTES when set, otherwise 1MB).
You can cap payload sizes with TYWRAP_CODEC_MAX_BYTES (responses) and TYWRAP_REQUEST_MAX_BYTES
(requests) to keep JSONL traffic bounded.
import { PyodideBridge } from 'tywrap/pyodide';
const bridge = new PyodideBridge({
indexURL: 'https://cdn.jsdelivr.net/pyodide/v0.24.1/full/'
});
await bridge.init();import { NodeBridge } from 'npm:tywrap'; // Deno
import { NodeBridge } from 'tywrap'; // Bun// tywrap.config.ts
import { defineConfig } from 'tywrap';
export default defineConfig({
pythonModules: {
'pandas': { classes: ['DataFrame'], functions: ['read_csv'] },
'numpy': { alias: 'np' }
},
output: { dir: './src/generated' }
});See Configuration Guide for all options.
| Python | TypeScript | Notes |
|---|---|---|
numpy.ndarray |
Uint8Array / array |
Arrow or JSON |
pandas.DataFrame |
Arrow Table / object[] |
Arrow or JSON |
scipy.sparse.* |
SparseMatrix |
CSR, CSC, COO |
torch.Tensor |
TorchTensor |
CPU only |
sklearn estimator |
SklearnEstimator |
Params only |
datetime, Decimal, UUID, Path |
string |
Standard formats |
For Arrow encoding with numpy/pandas:
import { registerArrowDecoder } from 'tywrap';
import { tableFromIPC } from 'apache-arrow';
registerArrowDecoder(bytes => tableFromIPC(bytes));npm install
npm testSee CONTRIBUTING.md for guidelines.
MIT © tywrap contributors