React Native
Feature requests for React Native apps, without a native module
Most feedback tools tell React Native developers to "use the web widget in a WebView" and leave it at that. It works, but the details matter: Expo managed apps cannot add native modules, WebView keyboards misbehave, and a board that ignores the platform gives you one vote count for two very different audiences. This page covers adding feature requests to a React Native app the way it should be done, with Expo and bare workflow code, and shows what you get on the dashboard side.
For a React Native app, open a hosted feature request board with expo-web-browser (or react-native-inappbrowser-reborn in a bare project). It is one JavaScript call, works in Expo Go and EAS builds, needs no native module, and serves iOS and Android from one board. Users vote in a sheet that looks native; you get statuses, merge, and per-platform analytics. Free for 10 requests, then $5 a month.
The React Native feedback problem
React Native teams ship to iOS and Android from one codebase, and that is exactly what makes feedback messy. App Store reviews and Google Play reviews are separate systems. Your support inbox mixes both. When five iPhone users and thirty Android users ask for the same feature, you only find out if someone counts by hand.
Native SDKs are the second problem. Canny, Featurebase, and most feedback tools have no React Native package at all; their advice is a WebView. Tools that do ship native modules break Expo's managed workflow and add another dependency to every upgrade. For a small team on a tight React Native upgrade cycle, each native module is a future afternoon lost.
A hosted board avoids both. It is a URL, so Expo Go, EAS builds, and bare projects all open it the same way, and both platforms write to one project. The dashboard records which platform each request and voter came from, so the iOS and Android split is a chart rather than a spreadsheet.
Expo: open the board with expo-web-browser
Install the package and call it from a settings row. On iOS it presents SFSafariViewController; on Android it uses Chrome Custom Tabs. Both keep the user inside your app and share browser storage, which is how votes persist between visits.
npx expo install expo-web-browserimport * as WebBrowser from "expo-web-browser";
import { Pressable, Text } from "react-native";
const BOARD_URL = "https://pickafeature.com/b/your-app";
export function FeatureRequestsRow() {
const open = () =>
WebBrowser.openBrowserAsync(BOARD_URL, {
presentationStyle: WebBrowser.WebBrowserPresentationStyle.PAGE_SHEET,
toolbarColor: "#6366f1",
enableBarCollapsing: true,
});
return (
<Pressable onPress={open} accessibilityRole="button">
<Text>Feature requests</Text>
</Pressable>
);
}Replace the board URL with the one from your dashboard's Projects page. There is nothing else to configure, and nothing to update when the board gains features, because the board is served by us.
Bare React Native: in-app browser or Linking
Without Expo, react-native-inappbrowser-reborn gives you the same Safari sheet and Custom Tabs behaviour:
import { InAppBrowser } from "react-native-inappbrowser-reborn";
import { Linking } from "react-native";
const BOARD_URL = "https://pickafeature.com/b/your-app";
export async function openFeatureRequests() {
if (await InAppBrowser.isAvailable()) {
await InAppBrowser.open(BOARD_URL, {
modalPresentationStyle: "pageSheet",
toolbarColor: "#6366f1",
showTitle: true,
});
} else {
await Linking.openURL(BOARD_URL);
}
}If you would rather avoid any native dependency, Linking.openURL alone opens the board in the system browser. It leaves your app, which is a worse experience, but it is a zero-dependency fallback that works everywhere.
Embedding the board in a screen with react-native-webview
To make the board a tab or a full screen in your navigator, render a page that embeds the pick a feature web widget in inline mode inside react-native-webview. You can also pass the signed-in user's id so votes follow their account across devices:
import { WebView } from "react-native-webview";
const html = (apiKey: string, userId?: string) => `
<!doctype html><meta name="viewport" content="width=device-width, initial-scale=1">
<div id="board"></div>
<script src="https://pickafeature.com/sdk/v1/pickafeature.js"></script>
<script>
PickAFeature.init({
apiKey: "${apiKey}",
container: "#board",
theme: "auto",
user: ${userId ? `{ id: "${userId}" }` : "undefined"}
});
</script>`;
export function BoardScreen({ userId }: { userId?: string }) {
return (
<WebView
originWhitelist={["*"]}
source={{ html: html("YOUR_PROJECT_KEY", userId), baseUrl: "https://pickafeature.com" }}
javaScriptEnabled
domStorageEnabled
/>
);
}Keep domStorageEnabled on; the widget stores the device id and vote state in localStorage. The project key is public by design (it ships inside every mobile binary) and is rate-limited per project on the server. Full option list in the web widget docs.
Triage, merge, and see iOS versus Android
Every submission lands as pending in the dashboard and stays hidden from users until you approve it. That single step removes spam and support tickets from the public board. From there you drag cards across a kanban: under review, planned, in progress, completed. Users see the new status the next time they open the board.
Duplicates are the daily chore of any feedback board, and React Native apps get them twice, once per platform. Drag one card onto another and the merge dialog shows both, lets you keep or combine the title and description, and moves votes and comments across with each voter counted once. The analytics page then charts users and requests by iOS, Android, and web, which is the number you actually want before deciding whether to build a platform-specific feature.
How pick a feature fits a React Native team
pick a feature is a small, flat-priced feedback board for developers who pay for their own tools. Free for one project and 10 feature requests. $5 a month for three projects with unlimited requests. $15 a month for unlimited projects. No per-seat or per-tracked-user pricing, so growth on either platform never changes the bill.
For React Native you get the hosted board for Expo and bare projects, the web widget for WebView screens, one dashboard with merge and per-platform analytics, and email notifications when requests arrive. A React Native package is on the roadmap and prioritised by demand; if you want it, say so, and it goes on our own board.
Frequently asked questions
Does this work in Expo Go and with EAS Build?
Yes. expo-web-browser is part of the Expo SDK, so the hosted board opens in Expo Go during development and in EAS production builds without a custom dev client. The WebView approach needs react-native-webview, which is also supported in managed projects.
Is there a React Native SDK or npm package?
Not yet. Today React Native apps use the hosted board through an in-app browser or the web widget inside a WebView. A dedicated React Native package is on the roadmap and prioritised by demand. Both current routes write to the same project, so switching later loses nothing.
Can votes be tied to my app's user accounts?
With the WebView approach, yes: pass the signed-in user's id to PickAFeature.init or call PickAFeature.identify after login, and votes follow that id across devices. With the hosted board in an in-app browser, votes are per browser storage instead.
Will iOS and Android users see the same board?
Yes. Both open the same project URL, so vote counts are combined. The dashboard records the platform of each submission and voter, and the analytics page shows the iOS-versus-Android split for both users and requests.
What does it cost?
Free for one project and 10 feature requests, no card required. Starter is $5 a month for three projects and unlimited requests. Unlimited is $15 a month for unlimited projects. Pricing is flat regardless of installs or team size.