Adding Event Emitters to Your TurboModule in Swift

youtube-cover
Teachers
Oskar Kwaśniewski
Software Developer
@
Callstack

TurboModules don’t just expose functions, they can also push information from native to JavaScript. In this episode, Oskar shows how to extend the Local Storage TurboModule from Episode 1 with an event emitter that notifies JS whenever a new key is added. You’ll see how event types flow from TypeScript through Codegen into Objective‑C and Swift, and how to wire everything so JavaScript can subscribe safely and respond in real time.

Adding event types to the TypeScript spec

Oskar introduces the idea of emitting events when native state changes, such as when a new key is added in Local Storage. He adds an event payload type (key, value) and a new Codegen event field. After rerunning Codegen, new interfaces become available on the native side.

Understanding the newly generated native interfaces

Codegen now outputs a NativeLocalStorageSpecBase interface containing the auto‑generated emitOnKeyAdded method. Oskar shows how this sits alongside the existing TurboModule protocol and explains why the module must now inherit from this new base.

Implementing event emission in Swift

The Swift class gains a stored callback (onKeyAdded) and a custom initializer that accepts this closure. Oskar walks through marking the closure @escaping, storing it, and triggering it inside setItem only when a new key is created.

Wiring the Objective‑C Layer

Because the Swift initializer changed, the Objective‑C class must now call initOnKeyAdded: and forward the emitted dictionary back to JS via the generated emitOnKeyAdded. Oskar fills in the placeholders and validates that compilation succeeds.

Avoiding retain cycles

Oskar highlights a subtle memory bug caused by the Swift closure capturing self strongly, while Objective‑C also retains the Swift instance, forming a retain cycle. He fixes it by using a weak reference, breaking the circular ownership.

Subscribing to events in JavaScript

On the JS side, a useEffect subscription listens for onKeyAdded events and shows an alert when they occur. A new button writes a random key to trigger the event, and Oskar verifies the flow step‑by‑step in the Xcode debugger.

Resources

Learn how to emit native events from a Swift TurboModule and subscribe to them in JavaScript, including proper memory management and Codegen integration.

Heading 1

Heading 2

Heading 3

Heading 4

Heading 5
Heading 6

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.

Block quote

Ordered list

  1. Item 1
  2. Item 2
  3. Item 3

Unordered list

  • Item A
  • Item B
  • Item C

Text link

Bold text

Emphasis

Superscript

Subscript

TurboModules feel powerful but risky?

We help teams use them with confidence in real production apps.

Let’s chat
Link copied to clipboard!
//
Insights

Learn more about React Native

Stay up to date with our latest insights on React, React Native, and cross-platform development from the people who build the technology and scale with it daily.

//
insights

Learn more about React Native

//
React Native

We can help you move
it forward!

At Callstack, we work with companies big and small, pushing React Native everyday.

React Native Performance Optimization

Improve React Native apps speed and efficiency through targeted performance enhancements.

On-device AI

Run AI models directly on iOS and Android for privacy-first experiences with reliable performance across real devices.

AI Knowledge Integration

Connect AI to your product’s knowledge so answers stay accurate, up to date, and backed by the right sources with proper access control.

Generative AI App Development

Build and ship production-ready AI features across iOS, Android, and Web with reliable UX, safety controls, and observability.