Let's be honest, an app without a share button feels incomplete. Sharing is the engine of organic growth—it turns your users into your best marketers. When someone shares a cool feature, a high score, or an interesting article from your app, they're giving it a personal endorsement.
For us React Native developers, adding this feature boils down to two main choices: using the simple, built-in Share API or bringing in the heavy-hitting react-native-share library for more complex scenarios. We'll break down both, with plenty of code you can use right away.

Why Sharing Is a Must-Have, Not a Nice-to-Have
Ever since its launch back in 2015, React Native has become a powerhouse, with major players like Instagram and Tesla building their apps on it. Today, data from Enlyft shows that 43,149 companies are using React Native, and 33% of that market is in the United States alone. In this massive ecosystem, features that drive engagement are what separate a good app from a great one.
That’s where a library like react-native-share really shines. It provides the tools to build the kind of seamless sharing experiences users expect, making it a go-to for countless projects.
Choosing Your Sharing Tool
Before you write a single line of code, you need to decide which approach fits your app. This choice depends entirely on what you need to share.
The Built-in
ShareAPI: This is already part of the React Native core, so there's nothing to install. It's fantastic for sharing simple text or a URL. If you're building an MVP or just need basic "share this link" functionality, this is your quickest path.The
react-native-shareLibrary: This third-party package is your solution for anything more advanced. It lets you share local files, photos, base64 data, and even open a specific app like WhatsApp or Instagram with your content ready to go. To let users share photos from their device, you’ll typically use this library alongside a tool for selecting images. Our guide on implementing an image picker in React Native is a great resource for that.
My Advice: Start with the built-in
ShareAPI if you're only sharing a link or a quick message. If your roadmap includes sharing files, multiple items, or targeting specific social apps, just go withreact-native-sharefrom the start. It'll save you a refactor later.
To make the decision even clearer, here’s a quick look at how the two stack up.
React Native Share API vs react-native-share Library
This table gives you a high-level comparison to help you choose the right sharing solution for your app's needs.
| Feature | Built-in 'Share' API | react-native-share Library |
|---|---|---|
| Setup | None required (part of core) | Installation & linking required |
| Basic Sharing | Excellent for text & URLs | Excellent for text & URLs |
| File Sharing | No | Yes (local files, base64) |
| Social-Specific | No | Yes (e.g., share to Instagram) |
| Complexity | Low | Moderate (due to configuration) |
Ultimately, both are great tools. The built-in API offers speed and simplicity, while react-native-share provides the power and flexibility needed for more feature-rich applications.
When you first decide to add a sharing feature to your React Native app, your first stop should almost always be the built-in Share API. It’s baked right into the framework, which means you don't have to install or link a single thing. It just works.
This makes it perfect for getting off the ground quickly. If all you need is to let users share a simple piece of text or a URL—say, for an MVP or a content-focused app—the built-in API is often all you'll ever need.
Putting the Share API to Work
The core of the API is a single, elegant method: Share.share(). Calling this asynchronous function triggers the native share dialog on both iOS and Android, letting the user choose where to send your content.
Let’s see what this looks like in practice. Imagine you want a button that shares the link to an article. Here’s how you’d wire that up in a modern functional component.
import React from 'react';
import { Share, View, Button } from 'react-native';
const ShareExample = () => {
const onShare = async () => {
try {
const result = await Share.share({
message: 'Check out this awesome article I found! | React Native Coders',
url: 'https://reactnativecoders.com/latest-article/react-native-share',
title: 'React Native Share Guide' // Android only
});
if (result.action === Share.sharedAction) {
if (result.activityType) {
// This tells you which app the user shared to on iOS
console.log('Shared via:', result.activityType);
} else {
// This just means it was shared, common on Android
console.log('Content shared successfully!');
}
} else if (result.action === Share.dismissedAction) {
// The user swiped down or hit cancel
console.log('Share dialog was dismissed.');
}
} catch (error) {
// It's good practice to handle errors, just in case
alert(error.message);
}
};
return (
<View style={{ marginTop: 50 }}>
);
};
export default ShareExample;
As you can see, we wrap the Share.share() call in a try...catch block. This is a solid habit for catching any potential hiccups if the sharing process fails for some reason.
Breaking Down the Options and Results
The Share.share() method takes a content object with a few straightforward properties:
message: This is your main payload—the text you want to share. It's the one truly universal option that works everywhere.url: A URL you want to attach. On many apps and platforms, this can generate a nice-looking link preview. On iOS, themessageandurlare typically sent together.title: This is an Android-only property. It acts as a subject line and is especially useful when a user shares to an email client.
Once the user interacts with the share sheet, the promise resolves with a result object. This is where you get feedback on what happened.
A Pro Tip from Experience: Pay close attention to the
actionproperty in the result. You can check if the user actually completed the share (Share.sharedAction) or just backed out (Share.dismissedAction). This is incredibly useful for analytics or even just for showing a simple "Thanks for sharing!" message.
The activityType is another handy piece of information, but it's primarily an iOS feature. It gives you the bundle identifier of the app the user shared to (e.g., com.apple.mobilenotes.SharingExtension).
The real beauty of the built-in React Native Share API is its simplicity. It handles all the native, platform-specific code for you. While it won't let you share local files (like images or PDFs) or do advanced things like targeting a specific app, it absolutely nails its job: giving you a reliable, no-fuss way to share basic content. For many projects, it's the right tool for the job.
React Native’s built-in Share API is great for simple text or link sharing. But what happens when you need more? What if your app needs to share a local photo, a PDF invoice, or even a video file? That’s when you’ll quickly hit the limits of the core API and need to reach for a more robust solution.
This is exactly where the react-native-share library comes in. It’s the community-standard tool for handling just about any sharing scenario you can throw at it. It does require a bit more legwork to set up, but the payoff is huge, giving you the kind of fine-grained control that professional apps demand on both iOS and Android.
Installation and Setup
First things first, let's get the package into your project. You can add it using either npm or Yarn, just like any other dependency.
Using npm
npm install react-native-share –save
Using Yarn
yarn add react-native-share
For recent versions of React Native, autolinking should handle most of the native connections. However, for iOS, you still need to install the Pods to link the native code.
cd ios && pod install && cd ..
This simple command syncs up your iOS project with the new native dependency. With the basic installation done, we can move on to the platform-specific configurations where the real work begins.
From the code you write to the user tapping the share button, the process follows a clear path.

This flow is fundamental to mobile development—your code prepares the content, a trigger initiates the action, and the OS presents the final sharing options to the user.
Working with the Share.open Method
The heart of this library is the Share.open(options) method. While it looks similar to the built-in API, its options object is far more powerful, giving you much deeper control over the shared content.
While react-native-share extends React Native's core API for opening native dialogs, it significantly enhances what you can do. For example, a basic call like Share.open({title: 'Share this!', message: 'Check it out!', url: 'https://example.com'}) covers many common cases. But this library also adds crucial methods like shareSingle, which lets you target a specific app like Instagram (social: Share.Social.INSTAGRAM)—a must-have feature for social-media-focused apps. If you want to dive deeper into these capabilities, you can find more insights on React Native sharing on tricentis.com.
Let's see it in action with a real-world example: sharing an image file stored locally on the user's device.
import Share from 'react-native-share';
const shareLocalImage = async () => {
// Make sure your path is correct and has the file:// prefix
const imagePath = 'file:///path/to/your/local/image.jpg';
const shareOptions = {
title: 'Share this Image',
url: imagePath,
failOnCancel: false, // Prevents promise rejection when user cancels the share
};
try {
await Share.open(shareOptions);
} catch (error) {
console.log('Error => ', error);
}
};
Pay close attention to the file:// prefix in the URI. This is essential for the library to locate and handle the local file correctly.
Dealing with Android's FileProvider
One of the first hurdles you'll likely encounter is sharing local files on Android. Since Android Nougat (API 24), apps are restricted from sharing file:// URIs directly to prevent security vulnerabilities. If you try, your app will crash with a FileUriExposedException.
The solution is to use a content:// URI, which is securely generated by a FileProvider. This requires a little bit of native configuration.
First, you need to declare the FileProvider in your AndroidManifest.xml file, placing it inside the <application> tag.
Next, create a new file named provider_paths.xml inside android/app/src/main/res/xml/. This file tells the FileProvider which directories your app is allowed to share files from.
This setup grants your app permission to share files from its cache and internal file directories. It's a non-negotiable step for getting file sharing to work reliably on modern Android devices.
Key Takeaway: If file sharing is failing silently or crashing on Android, a misconfigured
FileProvideris almost always the culprit. Double-check yourAndroidManifest.xmlandprovider_paths.xmlfor any typos or incorrect paths.
Handling iOS Specifics
Although iOS is often more straightforward, it has its own quirks, especially when you want to share directly to specific apps like WhatsApp or Instagram. To make this work, you need to add the LSApplicationQueriesSchemes key to your Info.plist file.
This entry gives your app permission to check if other specific apps are installed on the device. Without it, your app has no way of knowing if Instagram is available, and the direct share option simply won't appear.
Here’s what you would add to ios/[YourAppName]/Info.plist to enable sharing to WhatsApp and Instagram:
LSApplicationQueriesSchemes
whatsapp
instagram
instagram-stories
Once this is in place, react-native-share can correctly detect and open these target applications.
Sharing Directly to a Single App
A truly powerful feature of react-native-share is the shareSingle method. It lets you skip the generic system share sheet and open a specific app directly, which makes for a much smoother user experience.
Here’s how you could share an image directly to a user's Instagram Stories.
import Share from 'react-native-share';
const shareToInstagramStory = async () => {
// The image needs to be in base64 format for this to work
const imagePath = 'data:image/jpeg;base64,' + base64ImageData;
const shareOptions = {
method: Share.InstagramStories.SHARE_BACKGROUND_IMAGE,
backgroundImage: imagePath,
social: Share.Social.INSTAGRAM_STORIES,
};
try {
// We use shareSingle instead of open
await Share.shareSingle(shareOptions);
} catch (error) {
console.log('Error => ', error);
}
};
This snippet shows how to share a base64-encoded image using shareSingle. The method, paired with the Share.Social enum, gives you a clean and direct API for targeted sharing—something the built-in API just can't do. If you're looking for more great tools like this, check out our guide on finding quality React Native NPM packages.
Sharing Within the Expo Ecosystem
If you're working within the Expo ecosystem, you're in for a treat when it comes to implementing sharing. Expo beautifully abstracts away the native configuration headaches you’d normally face in a bare React Native project. Forget about wrestling with Android's FileProvider or iOS's Info.plist—the expo-sharing library handles all that heavy lifting for you.

The library is designed to play nicely with other Expo APIs, creating a wonderfully cohesive experience. You'll find that you can build out complex features, like sharing a freshly taken photo or a generated PDF, with a surprisingly small amount of code.
Getting Started with Expo Sharing
Adding the library to your project is a single command. Pop open your terminal and run:
npx expo install expo-sharing
It's really important to use expo install here. This command is smart enough to grab the specific version of expo-sharing that’s compatible with your project's Expo SDK version, which saves you from the nasty version-mismatch bugs that can be a real pain to track down.
Once that's done, you're ready to use the library's core function: Sharing.shareAsync(). This method is your gateway to the native share sheet. Just give it a local file URI, and it will pop up the familiar dialog asking the user which app they want to send the file to.
A Real-World Example: Sharing a PDF
Let's look at a common scenario: your app generates an invoice or a report, and the user needs to share it. We can combine expo-print with expo-sharing to make this happen in just a few lines of code.
We'll start by generating a PDF from some basic HTML, and then we'll immediately pass its local file path to the sharing module.
import React from 'react';
import { View, Button } from 'react-native';
import * as Print from 'expo-print';
import * as Sharing from 'expo-sharing';
const PDFSharingComponent = () => {
const createAndSharePdf = async () => {
const htmlContent = '
Invoice #123
Thank you for your business!
';try {
// First, create the PDF from our HTML.
const { uri } = await Print.printToFileAsync({ html: htmlContent });
console.log('PDF generated at:', uri);
// It's a good practice to check if sharing is even possible on the device.
if (!(await Sharing.isAvailableAsync())) {
alert("Uh oh, sharing isn't available on this device.");
return;
}
// Now, open the share dialog with the PDF's local URI.
await Sharing.shareAsync(uri);
} catch (error) {
console.error('Error creating or sharing PDF:', error);
alert('Something went wrong while trying to share the PDF.');
}
};
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
);
};
export default PDFSharingComponent;
This snippet really showcases the power of the Expo ecosystem. What could have been a complex, platform-specific task becomes a simple, elegant flow of logic.
The Trade-Offs: When to Use Expo Share
So, what's the catch? The biggest benefit of expo-sharing is its incredible simplicity and speed. It meshes perfectly with other modules like expo-file-system and expo-camera, making it dead simple to share assets you create right inside your app.
The trade-off is in its flexibility.
expo-sharingis laser-focused on one thing: sharing local files. It doesn't have the advanced features ofreact-native-share, like sharing base64 data directly or opening a specific social app like Instagram or WhatsApp with pre-filled content.
This makes the decision pretty straightforward:
- Go with
expo-sharingif you're in the Expo ecosystem and your main goal is to let users share local files (photos, videos, generated documents, etc.). It’s fast, reliable, and keeps you from touching native code. - Opt for
react-native-shareif your needs are more advanced. If you have to share directly to specific apps, work with base64 data, or need other fine-grained control, this is your library. Just be aware it might mean ejecting from Expo's managed workflow.
For the vast majority of apps built on Expo, expo-sharing hits the sweet spot between powerful features and ease of use. It’s an excellent tool to have in your belt. If you're building with Expo and want to dive deeper, our complete React Native Expo tutorial is a great place to start.
Wrestling with Sharing Bugs: Common Pitfalls and How to Fix Them
Let's be honest: getting the share feature to work perfectly on both platforms can sometimes feel like a game of whack-a-mole. You fix it for Android, and something on iOS breaks. You call the share function, and… silence. We’ve all been there.
This is my collection of battle-tested fixes for the most common—and frustrating—bugs you'll encounter when implementing sharing in React Native.
The Infamous Android FileProvider Black Hole
This is a classic. You're trying to share a local file on Android. You’ve written the code, you tap the button, and absolutely nothing happens. No share dialog, no error in the console, just a whole lot of nothing.
Nine times out of ten, the culprit is a misconfigured FileProvider. Modern Android is serious about security and won't let you pass around raw file:// URIs. Instead, you have to use a secure content:// URI, and that requires setting up a FileProvider correctly. If you mess this up, Android simply ignores the request without a word.
To fix this, you need to get two files exactly right. First up is your AndroidManifest.xml. Make sure this provider block is inside your <application> tags.
Next, check your res/xml/provider_paths.xml. This file tells your app which directories are safe to share from. A simple typo here will cause the silent failure we're trying to fix.
My Go-To Debugging Trick: If you’re still stuck, log the file path you're trying to share right before you call
Share.open(). Is the file actually where you think it is? Does the path in yourprovider_paths.xmlmatch the directory? Answering these two questions solves 90% of these Android file-sharing headaches.
Where Did My Apps Go? The Mysterious iOS Share Sheet
Over on iOS, you might run into a different kind of ghost. You want to share a photo directly to Instagram or a message to WhatsApp, but they’re completely missing from the share sheet, even though you know the apps are installed.
This isn't a bug; it's a feature. iOS sandboxing prevents your app from knowing which other apps are installed on the user's device for privacy reasons. To see them, you have to explicitly declare which app "schemes" you want to interact with.
The fix is to add the LSApplicationQueriesSchemes key to your Info.plist file. Just open ios/[YourProjectName]/Info.plist and pop this in to enable sharing to Instagram and WhatsApp.
LSApplicationQueriesSchemes
instagram
instagram-stories
whatsapp
Without this, your app is flying blind, and react-native-share has no way to know those other apps even exist.
Other Annoying Gotchas and Quick Fixes
Beyond those two big ones, a few smaller issues frequently trip developers up. Here’s a rapid-fire round of problems and their solutions.
- Base64 Sharing Fails on Android: Trying to share an image from a base64 string (
data:image/png;base64,...)? On Android, you must include theurlproperty in your share options, even if the value is just the base64 string itself. The library needs this to write the data to a temporary file before sharing. - Annoying "File Not Found" Errors: This one sounds obvious, but it's a common mistake. If you’re generating or downloading a file, make sure that process is fully complete before you try to share it. Asynchronous code can easily create race conditions where you try to share a file that doesn't exist yet.
- "Promise Rejection" When a User Cancels: By default, if a user hits "Cancel" on the share dialog,
react-native-sharerejects the promise. This isn't really an error, but it can fill your logs with noise. A simple fix is to setfailOnCancel: falsein your share options. This treats a cancellation as a neutral user action, not a bug.
Keep these tips in your back pocket. They’ll help you sidestep the most common issues and build a sharing experience that feels smooth and reliable for your users.
Common Questions About React Native Share
Even after following a guide, you'll inevitably run into some specific head-scratchers when you're in the thick of coding. Here are some of the most common questions I see from developers working with sharing features in React Native, along with practical, straight-to-the-point answers.
How Can I Share Directly to a Specific App Like WhatsApp or Instagram?
This is a very common requirement. To bypass the default system share sheet and send content directly to a single app, you’ll need to use the react-native-share library. The built-in Share API that comes with React Native simply can’t do this; it's designed to only open the generic system menu.
The library makes this pretty straightforward with its shareSingle method and a Share.Social enum. For example, if you wanted to let users share a photo directly to their Instagram Story, your code would look something like this:
import Share from 'react-native-share';
const shareToInstagramStory = async (base64ImageData) => {
const shareOptions = {
method: Share.InstagramStories.SHARE_BACKGROUND_IMAGE,
backgroundImage: data:image/jpeg;base64,${base64ImageData},
social: Share.Social.INSTAGRAM_STORIES,
};
try {
await Share.shareSingle(shareOptions);
} catch (error) {
console.error("Oops, something went wrong sharing to Instagram:", error);
}
};
Always, always wrap the shareSingle call in a try...catch block. This is non-negotiable. If the user doesn't have the target app (like Instagram) installed, the call will fail. Without a catch block, your app will crash, which is a terrible user experience.
What’s the Difference Between Sharing a Base64 String and a File Path?
The choice between using a file path or a base64 string really boils down to performance and how you manage memory in your app.
File Path (
file:///...): This is almost always the best option. When you share a path to a file, you're just telling the operating system where to find it. The OS then handles all the heavy lifting of reading and sharing the file. Your app's memory usage stays nice and low, which is crucial when you're dealing with large files like videos or high-res photos.Base64 String (
data:image/png;base64,...): This method takes the entire file, converts it into a gigantic string of text, and loads it all into your app's memory. From there, it passes that string to the sharing API.
Base64 is really only useful for small, dynamic bits of content that don't exist as a physical file on the device. If you try to share a large image or video this way, you're asking for trouble—it can slow your app to a crawl or, worse, cause an out-of-memory crash.
Can I Customize How the Native Sharing Dialog Looks?
The short answer is no. You have zero control over the look and feel of the native sharing UI, whether it's the iOS Action Sheet or the Android Chooser.
This is a deliberate design choice by Apple and Google to ensure a consistent, predictable experience for users across their entire device. Your customization options are limited to the data you send to the share sheet:
- The message text
- A URL
- The title (on Android)
- The actual file(s) being shared
If your app's branding absolutely requires a fully custom sharing interface, the only way forward is to build one yourself from scratch. You could create a custom modal with branded buttons for each service ("Share on WhatsApp," "Post to X"). Behind the scenes, each button would then call react-native-share's shareSingle method to target that specific app.
At React Native Coders, we focus on practical tutorials and expert insights to help you build and launch better apps, faster. To see more real-world guides, check us out at https://reactnativecoders.com.





















Add Comment