Blog

Hybrid Apps: Native Modules in React Native

On Monday, Oct 6, 2025
post image

React Native is a framework for building cross-platform applications with one codebase. But every team will eventually face a moment where using third-party packages cannot deliver the full experience—maybe the package you decided to implement has limited access to native platform APIs, does not allow full control, or has limited customizations that prevent you from meeting design requirements.

At those moments, you’ve got two options:

  1. Wait for a third-party library to support your requirements. Build your own native module.
  2. This is when you realize: stick with convenience, or take control by building it yourself. To see why this trade-off matters, let’s step back and understand what native modules actually are.

This is when you realize: stick with convenience, or take control by building it yourself. To see why this trade-off matters, let’s step back and understand what native modules actually are.

Let’s take a quick look at Native Modules

Native modules act as the bridge between React Native’s JavaScript layer and the platform APIs in Swift, Objective-C, Java, or Kotlin. Once registered, they work just like any JS module, but under the hood, they’re calling native code.

Most of the time, developers shortcut this by implementing a library from the community (which wraps the native layer for them). That works great until you run into real-world requirements.

Let’s imagine Speakic: a language learning app with a “Hold to Speak” button so users can practice pronunciation and listen to phrases out loud.

The fastest way to build it? Install react-native-tts, @react-native-voice/voice, and call:


import Tts from 'react-native-tts';
import Voice from "@react-native-voice/voice";

export default function HomeScreen() {
  // Rest of the code...

  const startListening = async () => {
	...
	await Voice.start("en-US")
	...
  }

  const stopListening = async () => {
	...
  	await Voice.stop()
	...
  }

  const speak = (item: string) => {
	...
	Tts.speak(item)
	...
  }

  // Rest of the code...
}

✅ Achieving cross-platform pronunciation, with almost no effort.

But the trade-offs show when third-parties begin causing problems:

  • Lag behind React Native updates
  • May include unnecessary dependencies or security vulnerabilities
  • You’re stuck waiting on maintainers if a critical feature breaks.

Midway through 2023, developers ran into an issue with the dependency react-native-voice:

  • After a user stopped speaking, the module would play a beep and stop recording instead of returning results.
  • Later, another bug popped up: if the matches property returned by the speech recognition callback was null, some implementations would crash.

The community reported the error:

While the community shared fixes, the official patch wasn’t merged right away, and developers had to fork the repository and apply the fix manually, or wait until the update was published.

In cases like this, writing your own module makes a big difference.

Why Build Your Own Native Module?

When you roll your own module (in Swift or Kotlin), you’re in charge of how it behaves. Here’s what that means in practice:

What you gain What it costs
Full control over behavior, even after OS updates Extra dev effort to write and maintain
Direct access to platform APIs Need to keep up with OS changes
Room for performance tweaks Complexity of bridging code
Fewer third-party dependencies Long-term maintenance responsibility

Think of it this way: would you rather fix those issues yourself today, or wait for someone else’s library to patch it later?

💡 Speakic’s speech features run on a small custom native bridge (Kotlin + Swift) we wrote to connect React Native with the system APIs. If you’d like to peek at the full implementation, the reference code is available here: 👉 check out the repo

When to Use Third-Party Modules?

Not every feature needs a custom build. Community modules can save weeks of work when:

  • The functionality is common and stable (e.g., picking images, handling device storage).
  • The library is actively maintained and widely adopted.
  • Speed of delivery matters more than fine-grained control.
  • Your team doesn’t have native iOS/Android expertise in-house.

It is all about balance: Use third-party libraries for standard features and create your own when the functionality you are building is the core of your product or when you need full control.

Why This Matters for Teams and Clients

Let’s break it down separately:

For Teams

  • Flexibility: You’re no longer blocked waiting for community packages to catch up.
  • Reduced Risk: No surprises if a maintainer disappears or drops support.
  • Skill Growth: Building bridges sharpens your team’s iOS/Android skills, which pays off across the stack.
  • Faster Innovation: You can ship features with brand-new platform APIs without delay.

For Clients

  • Reliability: Features keep working because the code is under your control.
  • Ownership of Roadmap: Updates happen on your schedule, not a maintainer’s.
  • Security: Fewer unknown dependencies reduce potential attack surfaces.
  • Competitive Advantage: Businesses can experiment with new platform features early and stand out in the market.

The Innovation Edge

Native modules speed up experimentation.

One thing to highlight about native modules is how they speed up experimentation. If Apple or Google release a new API, you do not have to wait months for the ecosystem to catch up, you can wire it yourself and ship a prototype next week.

For a product team, that’s a huge competitive edge. It means you’re not following trends, you’re testing them before others can. This accelerates innovation cycles and lets products differentiate faster.

For teams building hybrid apps, being able to create native modules gives them a competitive advantage.

Wrapping Up

Third-party modules make life easier, If your app needs a date picker, there’s no reason to reinvent it. The community already maintains great ones that work across iOS and Android.

But the real power of React Native shines when you build your own bridge to native APIs. Owning them means owning the experience end-to-end. That’s what makes hybrid apps truly flexible: the speed of React Native plus the control of native.

That’s what makes hybrid apps truly flexible, the speed of React Native combined with the control of native.

Sooner or later, you’ll need something that isn’t on npm or yarn, and the teams that can build it themselves have a significant advantage.

References

Share this post: