Skip to main content
Around 32 native bridges are dormant until your JavaScript calls them. You add the snippet directly to your web app — in a click handler, a lifecycle hook, or wherever makes sense for your product. No native code, no Xcode, no rebuild is required. Capwrapper’s runtime receives the call and executes the native behavior on the device. Always wrap bridge calls in an isNativeApp check so your web app continues to work in browsers:
if (window.isNativeApp) {
  // safe to call any NativeClass here
}
The features below are grouped by category.

Printing and sharing

Opens the native print dialog. You can print the current page, a remote PDF by URL, or any custom HTML string.
// Print the current page
NativePrint.printPage();

// Print a PDF from URL
NativePrint.printPDF({ url: 'https://example.com/invoice.pdf' });

// Print custom HTML
NativePrint.printHTML({ html: '<h1>Invoice #1024</h1><p>Amount due: $49.00</p>' });
Opens the native share menu (WhatsApp, Messages, Email, AirDrop, and any app the user has installed), or shows a native alert or confirm dialog instead of a browser popup.
// Open the native share sheet
NativeUI.share({
  title: 'Check this out',
  text: 'I found this on the app.',
  url: 'https://example.com/product/42',
});

// Show a native alert
NativeUI.alert({ title: 'Saved', message: 'Your changes have been saved.' });

// Show a native confirm dialog
NativeUI.confirm({
  title: 'Delete item?',
  message: 'This action cannot be undone.',
  confirmText: 'Delete',
  cancelText: 'Cancel',
  onConfirm: () => deleteItem(),
});

Scanning

Opens the device camera in a native scanner view. Supports QR codes, EAN-8, EAN-13, Code 128, and Code 39. Calls your callback the moment a code is detected.
NativeQRScanner.scan({
  onSuccess: (result) => {
    console.log('Scanned:', result.value, result.format);
    // result.format: 'QR_CODE' | 'EAN_13' | 'CODE_128' etc.
  },
  onCancel: () => console.log('Scanner dismissed'),
});
Opens a document scanning view with automatic edge detection, perspective correction, and image enhancement. Returns a cropped, enhanced image you can upload or display.
NativeDocScanner.scan({
  onSuccess: (result) => {
    // result.imageBase64 is a base64-encoded JPEG
    uploadDocument(result.imageBase64);
  },
});

Voice and maps

Starts the device’s native speech recognition engine. Useful for search fields, note-taking, and accessibility. The transcript is delivered to your callback as the user speaks.
NativeVoice.start({
  language: 'en-US',
  onResult: (transcript) => {
    document.getElementById('search-input').value = transcript;
  },
  onEnd: () => console.log('Recording finished'),
});

// Stop recording manually
NativeVoice.stop();
Opens the address or coordinates in Apple Maps (iOS) or Google Maps (Android), optionally starting turn-by-turn navigation.
// Open an address
NativeMaps.open({ address: '1 Infinite Loop, Cupertino, CA' });

// Open coordinates with navigation
NativeMaps.open({
  latitude: 37.3318,
  longitude: -122.0312,
  navigate: true,
});

Files and media

Downloads a file from a URL to the device’s Downloads folder with a native progress indicator. The user is notified when the download completes.
NativeDownload.download({
  url: 'https://example.com/report.pdf',
  filename: 'Q1-Report.pdf',
  onProgress: (percent) => updateProgressBar(percent),
  onComplete: () => showToast('Download complete'),
});
Opens the native file picker or photo library. Returns the selected file so you can upload it to your server or process it locally.
NativeFileUpload.pick({
  type: 'image', // 'image' | 'document' | 'any'
  onSelect: (file) => {
    const formData = new FormData();
    formData.append('avatar', file.blob, file.name);
    fetch('/api/upload', { method: 'POST', body: formData });
  },
});
Plays audio or video using the native media player. Audio continues playing when the app is moved to the background, and the lock screen controls appear automatically.
NativeMediaPlayer.play({
  url: 'https://example.com/podcast-episode-12.mp3',
  title: 'Episode 12 — Building Mobile Apps',
  artist: 'Dev Podcast',
  coverImage: 'https://example.com/cover.jpg',
});

NativeMediaPlayer.pause();
NativeMediaPlayer.stop();
Captures the current screen contents and returns the image as a base64 string. Useful for sharing, bug reports, or in-app feedback flows.
NativeScreenshot.capture({
  onSuccess: (result) => {
    // result.imageBase64 contains the PNG screenshot
    shareScreenshot(result.imageBase64);
  },
});

Notifications and engagement

Schedules a notification that appears in the device notification tray even when the app is closed. No server required for local notifications.
NativeNotifications.schedule({
  title: 'Your order has shipped',
  body: 'Order #5821 is on its way. Tap to track.',
  delaySeconds: 3600, // fire in 1 hour
  data: { orderId: '5821' },
});
Sending push notifications from your server requires a Firebase project. See Push notifications in the external setup guide.
Shows the native “Rate this app” dialog built into iOS and Android. Apple enforces a maximum of three prompts per year per user, so call this only at a natural high-engagement moment.
// A good moment: after a user completes their 5th task
if (user.completedTasks === 5) {
  NativeRating.requestReview();
}
Shows a native modal with a title, a message body, and a call-to-action button. Useful for feature announcements, upgrade prompts, or contextual help.
NativeMessaging.show({
  title: 'New feature available',
  message: 'You can now export reports as PDF directly from the dashboard.',
  ctaText: 'Try it now',
  onCta: () => router.push('/reports'),
});

Storage and data

Stores arbitrary string values in encrypted native storage. Data survives app restarts and OS-level background termination. Ideal for user preferences, cached tokens, or local state.
// Write a value
await NativeDatastore.set({ key: 'theme', value: 'dark' });

// Read a value
const theme = await NativeDatastore.get({ key: 'theme' });
console.log(theme.value); // 'dark'

// Remove a value
await NativeDatastore.remove({ key: 'theme' });
Stores sensitive values (tokens, PINs, secrets) in the iOS Keychain or Android EncryptedSharedPreferences. Also detects rooted or jailbroken devices so you can block access to security-sensitive features.
// Store a secret
await NativeSecurity.setSecret({ key: 'api_token', value: userToken });

// Retrieve a secret
const { value } = await NativeSecurity.getSecret({ key: 'api_token' });

// Check for root / jailbreak
const { compromised } = await NativeSecurity.isDeviceCompromised();
if (compromised) {
  showSecurityWarning();
}
Sends named events with optional parameters to Firebase Analytics. Requires a Firebase project — see Firebase Analytics in the external setup guide.
NativeAnalytics.logEvent({
  name: 'purchase_completed',
  params: {
    item_id: 'plan_pro',
    value: 49.00,
    currency: 'USD',
  },
});

Device and network

Returns information about the device type, screen dimensions, current orientation, and platform.
const info = await NativeDevice.getInfo();
// info.platform: 'ios' | 'android'
// info.isTablet: boolean
// info.screenWidth: number
// info.screenHeight: number
// info.orientation: 'portrait' | 'landscape'

if (info.isTablet) {
  enableTabletLayout();
}
Returns the current connection type, whether a VPN is active, and optionally runs a speed test.
const status = await NativeConnectivity.getStatus();
// status.type: 'wifi' | 'cellular' | 'none'
// status.vpnActive: boolean

if (status.type === 'none') {
  showOfflineBanner();
}

// Run a speed test
const speed = await NativeConnectivity.speedTest();
console.log(`Download: ${speed.downloadMbps} Mbps`);

UI and navigation

Sets the navigation bar title and toggles the side drawer open or closed from JavaScript.
NativeNavigation.setTitle({ title: 'My Orders' });

NativeNavigation.openDrawer();
NativeNavigation.closeDrawer();
Renders a native bottom tab bar with icons and labels. Tapping a tab posts a message to your web app so you can navigate to the correct page.
NativeTabBar.setTabs([
  { id: 'home', label: 'Home', icon: 'house' },
  { id: 'orders', label: 'Orders', icon: 'bag' },
  { id: 'profile', label: 'Profile', icon: 'person' },
]);

NativeTabBar.onTabSelect((tabId) => {
  router.push(`/${tabId}`);
});
Renders a native side drawer with a list of menu items and optional icons.
NativeSidebar.setItems([
  { id: 'dashboard', label: 'Dashboard', icon: 'gauge' },
  { id: 'settings', label: 'Settings', icon: 'gear' },
  { id: 'help', label: 'Help', icon: 'question-circle' },
]);

NativeSidebar.onItemSelect((itemId) => {
  router.push(`/${itemId}`);
});
Shows a multi-step onboarding flow the first time the user opens the app. Completion is stored in native storage so the flow never repeats unless you reset it.
NativeOnboarding.show({
  steps: [
    { title: 'Welcome', body: 'Track your orders in one place.', image: 'onboarding-1' },
    { title: 'Get notified', body: 'Enable push notifications to stay updated.', image: 'onboarding-2' },
    { title: "You're set", body: 'Tap Get started to open the app.', image: 'onboarding-3' },
  ],
  onComplete: () => router.push('/dashboard'),
});

Other bridges

Requests permission and reads the user’s contacts. Returns an array of names and phone numbers.
const { contacts } = await NativeContacts.getAll();
contacts.forEach((c) => {
  console.log(c.name, c.phone);
});
Creates an event in the device’s default calendar app. The user is shown a native confirmation before the event is saved.
NativeCalendar.addEvent({
  title: 'Team standup',
  startDate: '2026-04-15T09:00:00',
  endDate: '2026-04-15T09:30:00',
  notes: 'Daily 9 am standup via the app.',
});
Fires a callback whenever the device goes online or offline, giving you real-time control over your UI state.
NativeOffline.onStatusChange((status) => {
  if (status === 'offline') {
    showBanner('You are offline. Some features may be unavailable.');
  } else {
    hideBanner();
  }
});
Pushes a new version of your web app to users immediately, bypassing the app store review cycle. Ideal for content updates and bug fixes that do not require a native change.
await NativeOTA.checkForUpdate();
// Returns { available: boolean, version: string }

await NativeOTA.applyUpdate();
// Downloads and applies the update, then restarts the web layer
Preloads one or more URLs in the background so navigation to those pages feels instant. Also exposes a cache-clearing utility.
// Preload likely next pages
NativePerformance.preload(['https://yourapp.com/checkout', 'https://yourapp.com/profile']);

// Clear the cache (useful after a user logs out)
NativePerformance.clearCache();
Scans for nearby iBeacon or Eddystone BLE beacons. Useful for proximity-based features like indoor navigation, store check-ins, or attendance tracking.
NativeBeacon.startScanning({
  uuids: ['E2C56DB5-DFFB-48D2-B060-D0F5A71096E0'],
  onBeaconDetected: (beacon) => {
    console.log(`Beacon ${beacon.major}:${beacon.minor} — distance: ${beacon.proximity}`);
  },
});

NativeBeacon.stopScanning();
Registers your app as a share target so users can share URLs, text, images, and files into your app from Safari, Photos, and other apps. Requires external setup — see Share into app.
NativeShareInto.onReceive((payload) => {
  // payload.type: 'url' | 'text' | 'image' | 'file'
  if (payload.type === 'url') {
    router.push(`/save?url=${encodeURIComponent(payload.value)}`);
  }
});

If you use an AI builder such as Base44, Bolt, Lovable, Cursor, or Replit, paste the snippet above into your project and describe the feature. The AI can wire up the full integration for you.

Next steps

External setup features

Some bridges need an external account — Firebase, RevenueCat, AdMob, and more. Start here if you need push notifications, in-app purchases, or ads.

All 40 bridges

Return to the overview for a full table of every bridge and its tier.