tezvyn:

Creating a native module with a sync method

AI-drafted, machine-checkedintermediate
WHAT IT TESTS

native module mechanics across platforms.

OUTLINE

extend the RN base class, mark the method exported and synchronous, register in a package or bridging file.

WHAT THIS TESTS The interviewer wants the concrete mechanics: which base class or macro, which annotation marks a method synchronous, and how the module is registered so JavaScript can find it.

A GOOD ANSWER COVERS On Android you create a Kotlin (or Java) class extending ReactContextBaseJavaModule and override getName to return the JS-visible name. You annotate the exposed method with @ReactMethod, and to make it synchronous you set @ReactMethod(isBlockingSynchronousMethod = true); such a method can return a value directly instead of via callback. You then add a class implementing ReactPackage whose createNativeModules returns your module, and register that package in the host's getPackages. On iOS you create a class (Objective-C, or Swift with an Objective-C bridge) and call RCT_EXPORT_MODULE() to register it. A normal exported method uses RCT_EXPORT_METHOD, but for a synchronous one you use RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD, which returns a value directly. In Swift you expose the methods through an @objc interface and an .m file or bridging header. From JS you reach it via NativeModules.YourModule. You should caution that blocking synchronous methods run on the JS thread and must be fast, since they block JS execution.

COMMON WRONG ANSWERS Forgetting to register the package on Android or RCT_EXPORT_MODULE on iOS leaves the module undefined in JS. Using the regular @ReactMethod or RCT_EXPORT_METHOD and expecting a synchronous return is wrong; those are asynchronous on the legacy Bridge. Assuming all native calls can be synchronous ignores that only specially-flagged methods are, and only on the legacy architecture this needs the flag.

LIKELY FOLLOW-UPS Why are sync methods discouraged? They block the JS thread and historically only worked without remote debugging. How does the new architecture change this? TurboModules over JSI make synchronous calls first-class without the special macro. What types can cross? JSON-serializable primitives and structures.

ONE CONCRETE EXAMPLE Android: class MathModule(ctx) extends ReactContextBaseJavaModule(ctx) { override fun getName() = "MathModule"; @ReactMethod(isBlockingSynchronousMethod = true) fun add(a: Int, b: Int): Int = a + b }. iOS: RCT_EXPORT_MODULE() then RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(add:(NSInteger)a b:(NSInteger)b). JS calls NativeModules.MathModule.add(2,3) and gets 5 synchronously.

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.