Universal Modules — Write once, import anywhere. (A Claude Experiment)
umo compiles packages from any language into universal WebAssembly modules that can be imported natively by any other language.
Python package ──┐
│
Go module ───┼──► WASM Component ──► Import from Node, Python, Go, Rust...
│
npm package ───┘
Each programming language ecosystem has many useful libraries. Umo makes them available to every language.
# Install the humanize package as a universal module
umo pip-install humanize
# That's it. Now use it in JavaScript:import { intcomma, naturalsize, ordinal } from './umo_modules/humanize/index.js';
console.log(intcomma(1000000)); // "1,000,000"
console.log(naturalsize(3000000)); // "3.0 MB"
console.log(ordinal(42)); // "42nd"Full TypeScript support included — autocomplete, type checking, everything just works.
Python:
from redblacktree import rbtree
tree = rbtree()
tree.insert(5, 'five')
tree.insert(3, 'three')
tree.insert(7, 'seven')
print(tree.depth()) # 2
print(list(tree.inorder())) # [(3, 'three'), (5, 'five'), (7, 'seven')]Node.js (same types, same API):
import { Rbtree } from './umo_modules/redblacktree/index.js';
const tree = new Rbtree([]);
tree.insert(5, 'five');
tree.insert(3, 'three');
tree.insert(7, 'seven');
console.log(tree.depth()); // 2
console.log(tree.inorder()); // [[3,"three"],[5,"five"],[7,"seven"]]Types map directly: Python int → JS number, Python list → JS array. State persists across calls.
npm install -g umoumo requires these tools (installed automatically or via your package manager):
| Tool | Purpose | Install |
|---|---|---|
| Node.js 18+ | Runtime | nodejs.org |
| Python 3.11+ | Python compilation | python.org |
| componentize-py | Python → WASM | pip install componentize-py |
Install a Python package as a universal module.
# Install latest version
umo pip-install humanize
# Install specific version
umo pip-install humanize@4.15.0Output: Creates umo_modules/<package>/ with:
index.js— JavaScript bindingsindex.d.ts— TypeScript declarationsbindings/— WASM component and runtime
List available curated packages.
umo pip-list┌─────────────────┐
│ Python Package │
│ (humanize) │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Type Extraction │ Analyzes signatures, docstrings, type hints
└────────┬────────┘
│
▼
┌─────────────────┐
│ WIT Generation │ Creates WebAssembly Interface Types
└────────┬────────┘
│
▼
┌─────────────────┐
│ componentize │ Compiles Python + CPython to WASM
└────────┬────────┘
│
▼
┌─────────────────┐
│ jco transpile │ Generates JS bindings from WASM
└────────┬────────┘
│
▼
┌─────────────────┐
│ umo_modules/ │ Ready to import!
│ humanize/ │
└─────────────────┘
Implementation: umo uses the WebAssembly Component Model to create portable, typed interfaces between languages. Functions calls cross the language boundary with native performance — no JSON serialization, no HTTP overhead.
| Language | Status | Command |
|---|---|---|
| Python | Stable | umo pip-install <pkg> |
| TypeScript | Planned | umo npm-install <pkg> |
| Go | Planned | umo go-install <pkg> |
| Rust | Planned | umo cargo-install <pkg> |
| Language | Status |
|---|---|
| JavaScript/TypeScript | Stable |
| Python | Planned |
| Go | Planned |
| Rust | Planned |
import {
intcomma,
intword,
ordinal,
apnumber,
scientific,
metric
} from './umo_modules/humanize/index.js';
intcomma(1234567); // "1,234,567"
intword(1200000000); // "1.2 billion"
ordinal(3); // "3rd"
apnumber(5); // "five"
scientific(0.00042, 2); // "4.20 x 10⁻⁴"
metric(1500, "V", 3); // "1.50 kV"import { naturalsize } from './umo_modules/humanize/index.js';
naturalsize(300); // "300 Bytes"
naturalsize(3000); // "3.0 kB"
naturalsize(3000000); // "3.0 MB"
naturalsize(3000000000); // "3.0 GB"import { Rbtree } from './umo_modules/redblacktree/index.js';
// Create a red-black tree (self-balancing BST)
const tree = new Rbtree([]);
// Stateful operations
tree.insert(10, 'ten');
tree.insert(5, 'five');
tree.insert(15, 'fifteen');
// Query - returns native JS types
console.log(tree.depth()); // 2 (number)
console.log(tree.inorder()); // [[5,"five"],[10,"ten"],[15,"fifteen"]]import * as pd from './umo_modules/pandas/index.js';
// Create DataFrames
const df1 = await pd.DataFrame.create({ 'A': [1, 2], 'B': [3, 4] });
const df2 = await pd.DataFrame.create({ 'A': [5, 6], 'B': [7, 8] });
// Concatenate
const combined = await pd.concat([df1, df2]);
// Merge DataFrames
const left = await pd.DataFrame.create({ key: ['A', 'B'], val: [1, 2] });
const right = await pd.DataFrame.create({ key: ['A', 'C'], val: [3, 4] });
const merged = await pd.merge(left, right, 'inner', 'key');
// Check for missing values
console.log(await pd.isna(null)); // trueumo generates full TypeScript declarations from Python type hints:
// Auto-generated index.d.ts
export function intcomma(value: number, ndigits?: number): string;
export function naturalsize(value: number, binary?: boolean, gnu?: boolean): string;
export function ordinal(value: number): string;
export class Rbtree {
constructor(initial: any[]);
insert(key: number, value: string): void;
remove(key: number): void;
depth(): number;
inorder(): Array<[number, string]>;
}Your editor provides autocomplete, parameter hints, and type checking — just like native packages.
umo has been tested with 30+ Python packages across different categories. Here's a sample:
| Package | Category | Description |
|---|---|---|
pandas |
Data Science | DataFrames, data analysis (via Pyodide) |
networkx |
Data Science | Graph/network analysis (via Pyodide) |
sqlalchemy |
Database | SQL toolkit and ORM |
flask |
Web | Web microframework |
jinja2 |
Templating | Template engine |
beautifulsoup4 |
Parsing | HTML/XML parsing |
humanize |
Formatting | Human-readable numbers, dates, sizes |
click |
CLI | Command-line interface framework |
arrow |
Date/Time | Date and time handling |
redblacktree |
Data Structures | Self-balancing binary search tree |
View full list of validated packages — includes 30+ packages across web, data, CLI, utilities, and more.
Note: We validate that packages compile and run with basic tests. We don't maintain full test suite translations from the original Python packages.
- Python stdlib: Some stdlib modules aren't available in WASM (e.g.,
_ssl,mmap) - Native extensions: Some packages with C/Rust extensions require Pyodide runtime (pandas, networkx, numpy work; requests, pydantic don't)
- File I/O: Limited filesystem access in WASM sandbox
- Networking: No direct network access from WASM
- Go module compilation
- TypeScript/npm package compilation
- Import WASM modules into Python
- Import WASM modules into Go
- Browser support (run Python packages client-side)
- Package registry for pre-compiled modules
umo/
├── src/
│ ├── cli.ts # CLI entry point
│ ├── pip/
│ │ ├── package-resolver.ts # pip package resolution
│ │ ├── type-extractor.ts # Python type analysis
│ │ ├── wit-generator.ts # WIT interface generation
│ │ ├── wasm-compiler.ts # componentize-py integration
│ │ ├── js-generator.ts # JavaScript binding generation
│ │ └── dts-generator.ts # TypeScript declaration generation
│ ├── compiler/ # WASM compilation utilities
│ └── utils/ # Shared utilities
├── umo_modules/ # Compiled universal modules
└── tests/ # Test suite
# Clone and install
git clone https://github.com/AlaShiban/umo
cd umo
npm install
# Build
npm run build
# Run tests
npm test
# Development mode
npm run devQ: How big are the compiled modules? A: Python modules include the CPython runtime (~30-50MB). This is cached and shared across modules.
Q: Is it fast? A: Function calls have near-native overhead. The WASM boundary is much faster than HTTP/IPC. First load has a startup cost; subsequent calls are fast.
Q: What about async/await? A: Async functions are supported in the Python source. The JS bindings are synchronous for now.
MIT
Built on the incredible work of:
umo — Universal Modules for a polyglot world
