A comprehensive React Native library for implementing native app shortcuts on both iOS and Android platforms.
If this library helps you build amazing apps, consider buying me a coffee!
- π― iOS 3D Touch / Force Touch shortcuts - Native iOS app shortcuts
- π€ Android App Shortcuts (API 25+) - Modern Android shortcuts
- π Dynamic shortcuts - Update shortcuts at runtime
- π¨ Custom icons support - SF Symbols (iOS) & Drawable resources (Android)
- π Deep linking integration - Navigate directly to specific screens
- π± Cross-platform - Single API for both platforms
- π§ TypeScript support - Full type definitions included
- β‘ Production ready - Battle-tested in enterprise applications
npm install @mobigaurav/react-native-app-shortcuts
# or
yarn add @mobigaurav/react-native-app-shortcutsNote: This library requires React Native 0.60+ and uses auto-linking.
- Add to Podfile (if using manual linking):
pod 'RNAppShortcuts', :path => '../node_modules/@mobigaurav/react-native-app-shortcuts'- Update AppDelegate.m:
#import <RNAppShortcuts/RNAppShortcuts.h>
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
[RNAppShortcuts handleShortcutItem:shortcutItem];
completionHandler(YES);
}- Run pod install:
cd ios && pod install- Add package to MainApplication.java (if using manual linking):
import com.appshortcuts.RNAppShortcutsPackage;
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new RNAppShortcutsPackage() // Add this line
);
}- Handle shortcuts in MainActivity.java:
import com.appshortcuts.RNAppShortcutsModule;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RNAppShortcutsModule.handleShortcut(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
RNAppShortcutsModule.handleShortcut(intent);
}// Update shortcuts based on user authentication
const updateShortcuts = (isLoggedIn, userDevices) => {
const shortcuts = [];
if (isLoggedIn) {
shortcuts.push({
id: 'profile',
title: 'My Profile',
icon: 'person.circle',
data: { screen: 'Profile' }
});
// Add device-specific shortcuts
userDevices.slice(0, 2).forEach(device => {
shortcuts.push({
id: `device_${device.id}`,
title: device.name,
subtitle: `Control ${device.type}`,
icon: 'gear',
data: { screen: 'DeviceControl', deviceId: device.id }
});
});
} else {
shortcuts.push({
id: 'login',
title: 'Sign In',
icon: 'person.badge.key',
data: { screen: 'Login' }
});
}
AppShortcuts.setShortcuts(shortcuts);
};try {
await AppShortcuts.setShortcuts(shortcuts);
console.log('Shortcuts updated successfully');
} catch (error) {
console.error('Failed to update shortcuts:', error);
}import AppShortcuts from '@mobigaurav/react-native-app-shortcuts';
// 1. Set up shortcuts
AppShortcuts.setShortcuts([
{
id: 'compose',
title: 'Compose Message',
subtitle: 'Start a new conversation',
icon: 'plus.message', // iOS: SF Symbol, Android: drawable
data: { screen: 'Compose', action: 'new' }
},
{
id: 'search',
title: 'Search',
subtitle: 'Find messages and contacts',
icon: 'magnifyingglass',
data: { screen: 'Search' }
}
]);
// 2. Listen for shortcut activation
AppShortcuts.onShortcutPressed((shortcut) => {
console.log('Shortcut activated:', shortcut);
// Navigate based on shortcut data
switch (shortcut.data.screen) {
case 'Compose':
navigation.navigate('ComposeScreen');
break;
case 'Search':
navigation.navigate('SearchScreen');
break;
}
});
// 3. Handle app launch via shortcut
AppShortcuts.getInitialShortcut().then((shortcut) => {
if (shortcut) {
console.log('App launched via shortcut:', shortcut);
// Handle initial navigation
handleShortcutNavigation(shortcut);
}
});| Method | Description | Returns |
|---|---|---|
setShortcuts(shortcuts) |
Set dynamic shortcuts for the app | Promise<boolean> |
clearShortcuts() |
Remove all dynamic shortcuts | Promise<boolean> |
onShortcutPressed(callback) |
Listen for shortcut press events | EventSubscription |
getInitialShortcut() |
Get shortcut that launched the app | Promise<Shortcut | null> |
isSupported() |
Check if shortcuts are supported | boolean |
// Set up listener
const subscription = AppShortcuts.onShortcutPressed((shortcut) => {
// Handle shortcut
});
// Clean up listener
subscription.remove();interface Shortcut {
id: string; // Unique identifier
title: string; // Display title
subtitle?: string; // Optional subtitle
icon?: string; // Icon name/resource
data?: { [key: string]: any }; // Custom data payload
}
interface EventSubscription {
remove(): void;
}| Platform | Version | Features |
|---|---|---|
| iOS | 9.0+ | 3D Touch, Force Touch, Long Press |
| Android | 7.1+ (API 25+) | App Shortcuts, Pinned Shortcuts |
- iOS: Use SF Symbol names (e.g.,
plus.circle,gear,bell.fill) - Android: Use drawable resource names (e.g.,
ic_add,ic_settings)
Contributions are welcome! Here's how you can help:
- π Report bugs - Open an issue with details
- π‘ Suggest features - Share your ideas
- π§ Submit PRs - Fix bugs or add features
- π Improve docs - Help others understand
git clone https://github.com/mobigaurav/react-native-app-shortcuts.git
cd react-native-app-shortcuts
npm installMIT Β© Gaurav Kumar
- Originally developed for enterprise use
- Inspired by the React Native community's need for native shortcuts
- Thanks to all contributors and users!
- π§ Email: mobigaurav@gmail.com
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
Made with β€οΈ for the React Native community
If this library saved you time, consider buying me a coffee β