Binding Development
When to Use
- •Working in
bindings/python/,bindings/javascript/, orbindings/go/ - •Exposing a new
icl-corefunction to a language - •Debugging binding issues (type conversion, FFI)
- •Publishing a package (PyPI, npm, crates.io)
Context
Bindings are thin wrappers around icl-core. They convert language-native types to Rust types, call the Rust function, and convert back. Zero logic lives in bindings.
Reference files:
- •
ICL-Docs/PLAN.md— binding architecture diagram - •
crates/icl-core/src/lib.rs— the API being wrapped - •
bindings/<language>/— binding source
Procedure
- •Identify which
icl-corepublic function to expose - •Write the binding function (type conversion + call + conversion back)
- •The binding function must match the Rust API signature semantically
- •Error handling: convert
icl-core::Error→ language-native exception/error - •Add type hints/stubs:
- •Python:
.pyistub file - •JavaScript:
.d.tsTypeScript definitions - •Go: godoc comments
- •Python:
- •Write test: binding produces identical result to calling Rust directly
- •Test with the language's standard tooling (
pytest,npm test,go test) - •Verify package builds (
maturin build,wasm-pack build,go build)
Rules
- •ZERO logic in bindings — if you're writing an
ifstatement, it belongs inicl-core - •All bindings wrap the same Rust functions — identical semantics guaranteed
- •Error types map cleanly — don't swallow errors or change error messages
- •Bindings are versioned in lockstep — all packages share the same version number
- •Type conversions are explicit — no implicit coercion between language types and Rust types
Architecture
code
Python/JS/Go code
↓
Thin binding layer (~80-100 lines)
- Convert native types → Rust types
- Call icl-core function
- Convert Rust output → native types
- Convert Rust error → native exception
↓
icl-core (Rust) — ALL logic here
Technology per Language
| Language | Tool | Package format |
|---|---|---|
| Python | PyO3 + maturin | Wheel → PyPI |
| JavaScript | wasm-pack | WASM → npm |
| Go | cgo + cbindgen | Shared library → go module |
Anti-Patterns
- •Reimplementing parsing/validation in the binding language
- •Adding "convenience functions" that don't exist in icl-core
- •Different error handling behavior between bindings
- •Publishing bindings at different versions than core
- •Not generating type stubs/definitions