---
title: Building Cross-Platform SDKs: From FFI to WebAssembly
author: Mark Phelps
full_title: Building Cross-Platform SDKs: From FFI to WebAssembly
category: articles
url: https://blog.flipt.io/from-ffi-to-wasm
document_tags: ['backend', 'cgo', 'ffi', 'go', 'programming', 'rust', 'WASM', 'webassembly']
source: reader
date: 2025-03-13
created: 2025-03-13
last_highlighted_date: 2025-03-12
published_date: 2025-03-10
summary: đ A hybrid approach using WebAssembly (WASM) and native code enables truly portable cross-platform SDKs, addressing challenges posed by differing C standard libraries (glibc vs musl) and allowing for seamless language interoperability.
---
# Building Cross-Platform SDKs: From FFI to WebAssembly

## Metadata
- Author: [[Mark Phelps]]
- Full Title: Building Cross-Platform SDKs: From FFI to WebAssembly
- Category: #articles
- Published: 2025-03-10
- Document Tags: #backend #cgo #ffi #go #programming #rust #WASM #webassembly
- Source: reader
- Last Highlighted: 2025-03-12 15:59:37.270516+00:00
- URL: https://blog.flipt.io/from-ffi-to-wasm
## Summary
đ A hybrid approach using WebAssembly (WASM) and native code enables truly portable cross-platform SDKs, addressing challenges posed by differing C standard libraries (glibc vs musl) and allowing for seamless language interoperability.
## Highlights
- This post describes our journey building portable, cross-language SDKs for Flipt, and the unexpected technical challenges that forced us to rethink our approach a few times along the way. What started as a somewhat straightforward FFI implementation evolved into a complex exploration of C standard libraries, static linking, and eventually led us to WebAssembly. Along the way, we discovered that even in 2025, the dream of truly portable libraries remains surprisingly elusive - but our hybrid approach combining WASM with native code might be the key to cross-platform SDKs. ([View Highlight](https://read.readwise.io/read/01jp5h4pqwzfmc7wdmfgvg7e35))
- Tags: #đ» ai highlighted
- Then an idea came. What if we could 'wrap' our static library with a shared library that would load the static library at runtime? This way we could still build our static library with the `musl` C standard library and have a shared library that could be used in any language via FFI. ([View Highlight](https://read.readwise.io/read/01jp5h4prc09ah2d25qnwrspjt))
- Tags: #đ» ai highlighted
- All Linux first class ports are for systems using glibc only. Linux systems using other C libraries are not fully supported and are not treated as first class. ([View Highlight](https://read.readwise.io/read/01jp5h7h5a166b4gf7dwt690wr))
- WASM offered several compelling advantages:
1. Platform-independent bytecode format
2. No direct dependency on system libraries
3. Sandboxed execution environment
4. Isolated linear memory model ([View Highlight](https://read.readwise.io/read/01jp5h84h88jn9fzzqx0yta54z))
- WASM offered several compelling advantages:
1. Platform-independent bytecode format
2. No direct dependency on system libraries
3. Sandboxed execution environment
4. Isolated linear memory model ([View Highlight](https://read.readwise.io/read/01jp5h97x8w35nhbn2ywdx7fap))
- However, this expansion has revealed limitations in the core WASM specification:
1. No built-in threading support
2. No direct network access
3. Limited system interface capabilities
4. No direct file system access ([View Highlight](https://read.readwise.io/read/01jp5h8ebwe2a2bkzqs9b02zsc))
- However, this expansion has revealed limitations in the core WASM specification:
1. No built-in threading support
2. No direct network access
3. Limited system interface capabilities
4. No direct file system access ([View Highlight](https://read.readwise.io/read/01jp5h8zz5yc76erhqb118cff5))
- Working with WASM memory requires careful attention to prevent common issues:
1. **Memory Leaks**: Failing to call `deallocate` after allocating memory will cause leaks. This is particularly challenging in error paths where early returns might skip cleanup.
2. **Use After Free**: Reading from deallocated memory can cause undefined behavior. Always ensure memory is valid before access and copy data before deallocation if needed.
3. **Memory Management**: While WASM provides runtime bounds checking for memory access, you still need to carefully manage memory allocation and deallocation. The linear memory model requires explicit tracking of allocated regions.
4. **Resource Cleanup**: In concurrent scenarios, ensure proper cleanup when operations are cancelled or timeouts occur. ([View Highlight](https://read.readwise.io/read/01jp5ha348aw679ykz75p2jafr))
- We ended up using [wazero](https://github.com/tetratelabs/wazero), which is a pure Go runtime, and doesn't require CGO. Its API was similar enough to wasmtime's that we were able to make the switch relatively easily. ([View Highlight](https://read.readwise.io/read/01jp5hachbdf6cr145n5cqn4vt))