CLI tool
react-native-share/react-native-share avatar
react-native-share/react-native-share

The permission is named WRITE_EXTERNAL_STORAGE and it is off by default

Social share, sending simple data to other apps.

3,896 stars969 forksJavaMIT

At a glance

What is it?
react-native-share wraps the platform share sheet for React Native, with four native targets including Windows. Its one-shot usage example does not mention files, which is the module's actual reason to exist, and the storage permission that enables file sharing is opt-in and scoped to Android.
Who is it for?
react-native-share suits a React Native application that needs the native share sheet rather than a web-style share menu, and that wants one API across iOS, Android and Windows. Four things to know before you depend on it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • react-native-share/react-native-share3,896 ★ · +1
Star history
Repository2026-09-242026-11-14
react-native-share/react-native-share3.9k3.9k

1 Stars in the last 51 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

The storage permission that enables file sharing is opt-in, and that is a deliberate choice

There is exactly one permission in the whole document, it appears only inside the Expo configuration block, and it is guarded by a flag that defaults to off. The flag enables the addition of this to your Android manifest:

xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

That is the entire permission model of this library, and it is worth understanding what it means. Writing to external storage is what lets you hand the receiving app a real file path rather than an encoded blob, so this flag is the difference between sharing a file the other app can read and sharing something encoded. Keeping it opt-in means a project that only shares text or a URL never requests storage access at all, which is the right default on a platform where that permission has become progressively more restricted. It also means a project that does share files has to turn the flag on deliberately in configuration rather than discovering after the fact that a share silently fails. The README does not explain the failure mode either way, which is the gap: if you enable the flag and your target platform ignores it, you get a share that opens and delivers nothing useful, and nothing here tells you that is what happened.

Two install paths that differ in more than the package manager

There are two supported ways in, and the difference is not just which command you type. For Expo projects the README requires a managed workflow and an install through the Expo tooling, then a plugin entry in your app configuration that names the platforms you share to, then a prebuild step to regenerate the native projects. For bare React Native projects the instruction is conditional on your version: if you are on a recent enough React Native, or on the new architecture, you add the package with your package manager of choice and then run the CocoaPods install on iOS, which can be done either with a helper or by changing into the iOS directory and invoking the tool directly. The conditional matters. The README frames the older path as the one that needs more work, and points readers with problems on an older version to a separate documentation site rather than describing the old steps. That is a reasonable choice for a library that is still shipping updates, and it has a cost: a project stuck on an older version has no in-repository route to an answer. Note also that the iOS step is explicitly skippable on Android, which is the only place the README says plainly that the platforms are not symmetric.

Sharing to a specific app needs that app declared in two places on two platforms

The configuration block is doing more work than it appears to. You pass a list of iOS scheme identifiers and a list of Android package names, and the plugin writes them into your native manifests. On Apple platforms that means an application queries scheme array, which is how the system is told which apps your process is allowed to ask about at all. On Android it means a queries element listing the packages. If a target app is not declared, the share sheet will not offer it, and on iOS the failure is silent because the scheme is simply invisible to the operating system. The example lists four targets on each platform, and they do not map one to one. Facebook, Instagram, Twitter and a TikTok package scheme appear in both lists, but TikTok appears under a different scheme string on iOS than its package name on Android, which is a reminder that these are two unrelated identifier systems rather than one list of app names. The base64 sharing flag sits in the same block, so all three concerns, scheme declarations and the storage permission, are configured in one place. That is convenient and it means a mistake in one place has effects on both platforms.

The usage section shows one call, and the library ships three entry points

The entire documented usage is an import and a single call, with a resolved and a rejected handler. It takes an options object and returns a promise. That is the correct shape for the common case and it tells you almost nothing else. Meanwhile the documentation section explicitly refers to the full site for the other functions, so the API surface is acknowledged to be wider than what is shown. What is more interesting is what the example does not contain. The library's stated purpose is sharing messages and files, and the example shares neither: it passes options to a share sheet and logs the outcome. There is no demonstration of sharing a file from a local path, no demonstration of sharing base64 content, no demonstration of a per-app open rather than the generic sheet, and no mention of what the resolved value contains, which matters because the whole point of asking for a specific app is often to know whether that app actually took the share. So the example is a starting point and not a reference, and anyone whose use case involves files will need the external documentation to get past the first screen.

Four native targets and a podspec committed beside the JavaScript

The repository layout describes the shape better than the README does. There is an Android directory, an iOS directory, a Windows directory, and a single podspec file at the root that tells the iOS build system what to compile. Those are three genuinely separate native implementations behind one JavaScript API, and the Windows directory is the detail worth noticing: it means the library is not assuming a two-platform world, which most cross-platform tooling quietly does. The source is TypeScript, and the manifest records three separate published entry points, one for the module system bundlers expect, one for React Native's own resolver, and a types directory. The files list is explicit about what ships and what does not, including the source, both build outputs, the three platform directories, the podspec and the Expo plugin, with tests, fixtures and mocks all excluded. That is a well-kept package boundary, and the fact that the source is published rather than only the builds means you can read what you are depending on from inside your own project's dependencies directory.

Twenty-nine versions in one major, and a release process you can read in the tree

The package is on version twelve, and the recent history shows two releases on the same day, half an hour apart, in May 2026, with a patch release a couple of months earlier. That is the signature of an automated release process rather than a hand-cut one, and the evidence is all in the tree. There is a conventional-commits configuration, which is what lets tooling decide whether a change is a patch, a minor or a major purely from the commit message. There is a commit message linter as a development dependency, so a non-conforming message is caught before it can affect a version. There is a semantic-release badge in the README and a family of semantic-release plugins covering commit analysis, notes generation, the git step, the GitHub step and the npm publish step, each pinned separately. Husky with lint-staged and patch-package are also there, so hooks run on commit. The last commit on the default branch is dated 2026-08-31, and the newest release is from May, so the branch is running ahead of the published version. None of that is a problem; it just means the changelog and the branch will disagree until the next release cuts.

The repository contains a documentation site and an example app, both of which you can read

Two directories exist that are worth knowing about because they are the fastest way to answer a question the README does not. There is a website directory, which is the source of the documentation the README sends you to, so the documentation you are being referred to is in this repository and can be read without leaving it. There is an example application, and it is a real one rather than a stub. It has its own bundler configuration, its own TypeScript and lint configuration, its own Jest setup, Android and iOS project directories, a Gemfile for the Ruby side of the iOS tooling, and a directory of videos, which suggests recorded demonstrations of the library working. There is also a patches directory, which is the mechanism by which this project applies local modifications to its own dependencies, and a codeowners file, which means review responsibility is assigned at directory level rather than left to whoever happens to be free. For a library at version twelve with a long history, having the documentation, the working example and the review ownership all in the tree is the difference between a package you can evaluate and one you have to take on trust.

Editorial conclusion

react-native-share suits a React Native application that needs the native share sheet rather than a web-style share menu, and that wants one API across iOS, Android and Windows. Four things to know before you depend on it. Read the documentation site in the repository rather than the README, since the single documented call does not show file sharing and the example is a starting point rather than a reference. Declare every target app in the configuration block, because an undeclared app is invisible to the operating system and the failure on iOS is silent. Decide deliberately about the storage permission, since leaving it off means no file sharing and turning it on is a manifest change your users may see in permission listings. And read the example application, which is a working project in the tree and will answer faster than either the README or the docs.

Frequently asked questions

What is react-native-share?

It is a small React Native library for sharing messages and files with other apps, described as a tool for sending simple data to other applications. It wraps the platform share sheet, exposes one promise-returning call taking an options object, and ships native implementations for iOS, Android and Windows.

install react native share

There are two documented routes. Expo projects on a managed workflow install it through the Expo tooling, add a plugin entry to the app configuration naming the platforms you share to, then run the prebuild step. Bare React Native projects on a recent enough version, or on the new architecture, add it with the package manager and run the CocoaPods install on iOS, which is skippable on Android.

react native share image and text

The README documents one call taking an options object, and does not show an image or text example. File sharing specifically depends on an Android permission that is added only when the configuration flag for base64 sharing is enabled, and there is a documented note to add that permission to your Android manifest. For anything beyond the single call, the README directs you to the documentation site.

What permission does react-native-share need on Android?

One: a manifest permission to write to external storage. The plugin adds it only when the configuration flag for base64 sharing is set to true, so it is opt-in rather than automatic. Projects that share only text or a link never request storage access at all.

Why does the share sheet not show a target app?

Because target apps must be declared in your native manifests, and the configuration block is what writes them there. On Apple platforms the plugin adds scheme queries to the application queries array, and on Android it adds a queries element listing package names. The two lists use different identifier systems, so the same app appears under a scheme string on one platform and a package name on the other.

Official sources

  1. License: MIT
  2. Project website
  3. react-native-share/react-native-share on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/react-native-share-react-native-share.svg)](https://hysenlabs.com/projects/react-native-share-react-native-share)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/react-native-share-react-native-share.svg)](https://hysenlabs.com/projects/react-native-share-react-native-share)

Was this useful?