Node.js native addon bindings for lite3, a zero-copy binary serialization library.
This project is:
- Unofficial - Built independently of the lite3 project, with no affiliation to the original authors
- A learning exercise - Created primarily to explore Node.js native addon development
- Not production-ready - Use at your own risk
- Potentially inefficient - The JavaScript/N-API bridge may negate some of the performance benefits that lite3 offers in native contexts
npm install @jaydeebee/lite3-native-addonPrebuilt binaries are available for:
- Linux x64
- Linux arm64
- macOS arm64
Other platforms will fall back to source compilation (requires a C compiler and Python).
import{encode,decode,version}from'@jaydeebee/lite3-native-addon';// Encode an object to a binary bufferconstbuffer=encode({hello: 'world',count: 42});// Decode back to JavaScriptconstobj=decode(buffer);console.log(obj);// { hello: 'world', count: 42 }console.log(version());// Addon versionFor better performance with large objects where you only need a few fields, use Lite3Buffer.from() to create a lazy proxy that decodes values on-demand:
import{Lite3Buffer}from'@jaydeebee/lite3-native-addon';// Create from an object (type is inferred)constproxy=Lite3Buffer.from({users: [{name: 'Alice',age: 30},{name: 'Bob',age: 25}],metadata: {count: 2}});// Access properties naturally - decoded lazilyconsole.log(proxy.users[0].name);// 'Alice' - only this field is decodedconsole.log(proxy.metadata.count);// 2// Array methods work as expectedconstnames=proxy.users.map(u=>u.name);// ['Alice', 'Bob']constadults=proxy.users.filter(u=>u.age>=18);// Works with JSON.stringify, spreading, for...of, etc.console.log(JSON.stringify(proxy));constcopy={ ...proxy};for(constuserofproxy.users){console.log(user.name);}When creating a proxy from a buffer, the return type defaults to unknown for safety (like JSON.parse). Provide a type parameter when you trust the data source:
interfaceUser{name: string;age: number;}// From buffer - returns unknown by default (safe)constdata=Lite3Buffer.from(buffer);data.name;// TS error: 'unknown' has no property 'name'// With type parameter - returns User (trusted)constuser=Lite3Buffer.from<User>(buffer);user.name;// OK - full autocomplete and type checking// For untrusted sources, consider runtime validation:import{z}from'zod';constUserSchema=z.object({name: z.string(),age: z.number()});constvalidated=UserSchema.parse(Lite3Buffer.from(buffer));import{Lite3Buffer,$buffer,$decode}from'@jaydeebee/lite3-native-addon';// Check if a value is a Lite3Buffer proxyLite3Buffer.isLite3Buffer(proxy);// trueLite3Buffer.isLite3Buffer({});// false// Get the underlying bufferconstbuffer=Lite3Buffer.getBuffer(proxy);// Force full decode (escape hatch)constpojo=proxy[$decode]();// Access raw buffer via symbol (alternative)constrawBuffer=proxy[$buffer];| Scenario | decode() | Lite3Buffer.from() |
|---|---|---|
| Access all fields | Good | Similar |
| Access few fields from large object | Wasteful | Efficient |
| Repeated access to same field | Faster | Slightly slower (cached after first access) |
| Pass-through / routing | Decode + re-encode | Keep as buffer |
- Strings
- Numbers (stored as f64)
- Booleans
- Null
- Arrays
- Objects
Unsupported types (functions, undefined, symbols) are silently skipped during encoding.
MIT
Contributions are welcome.
- Open a pull request for bug fixes and minor improvements
- Use Angular commit message conventions (e.g.,
feat:,fix:,docs:) - For significant or invasive changes, please open an issue first to discuss the approach