Skip to content
Lucent
SEARCH LUCENT

Search guides, APIs, and examples.

GitHub

Very early and experimental. The language, the generated native code and every package API change without notice. Do not use Lucent in production.

How a call reaches native code

A call goes from your JavaScript through a proxy and JSI to your C++. Synchronous calls stay on the JS thread; async ones run on the Lucent thread.

A synchronous call, step by step, with the thread each step runs onJS THREADgreet("Ada")your JavaScriptproxygreet.lucent → the moduleJSIa host function callargument conversionchecks each value's typeyour C++greet runsreturn conversionC++ value → JS value"Hello, Ada!"returned to JavaScript
  1. The proxy hands the call to the Lucent TurboModule, through JSI.
  2. Argument conversion checks each value against its parameter's type, then copies it into C++.
  3. Your C++ runs on the JS thread, while JavaScript waits for it.
  4. Return conversion turns the C++ result into a JavaScript value.

A wrong value never reaches your code. It throws a TypeError that names the function and the argument:

terminal
TypeError: greet: argument 'name' must be a string, got a number
A async call, step by step, with the thread each step runs onJS THREADLUCENT THREADawait mean(values)your JavaScriptproxy · JSIa host function callargument conversionchecks, then copiesyour C++a coroutinepostedreturn conversionC++ value → JS valueposted backpromise resolvesin JavaScript
stats.lucent.ts
export async function mean(values: number[]): Promise<number> {
let sum = 0;
for (const value of values) sum += value;
return values.length > 0 ? sum / values.length : 0;
}
  • The arguments are checked and copied on the JS thread, so a wrong value throws at once rather than rejecting.
  • The body runs on the Lucent thread, a background thread, from its first line.
  • The result is posted back to the JS thread, converted, and resolves the promise. A thrown error rejects it instead.

All Lucent code runs under one lock, one piece at a time, like JavaScript. A synchronous call waits while async Lucent code runs, until that code reaches an await.

Numbers, strings, arrays and objects are copied. Class instances cross by reference and keep their identity, functions become callbacks, and promises stay promises. Type conversions has every type.