npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-ios-intents

v0.2.1

Published

React Native library for iOS Siri Shortcuts, Live Activities, and App Intents

Readme

react-native-ios-intents

React Native library for iOS Siri Shortcuts using App Intents.

Built with Nitro Modules for optimal performance.

Features

  • TypeScript-first - Configure shortcuts in TypeScript, generate Swift code
  • Full type safety with autocomplete - Generic types for shortcut identifiers and parameters
  • Dynamic state dialogs - Show confirmations/messages based on app state
  • Instant availability - Shortcuts work immediately after installation
  • Works when app is killed - Uses App Intents for background execution
  • Siri parameters - Capture user input (dates, names, notes) via Siri voice commands
  • Live Activities - Config-driven Lock Screen & Dynamic Island updates (iOS 16.2+)

Requirements

  • iOS 16.0+
  • React Native 0.74+
  • Xcode 15+

Installation

npm install react-native-ios-intents react-native-nitro-modules
cd ios && pod install

Setup

1. Generate Configuration

npx react-native-ios-intents generate

2. Define Shortcuts

Edit intents.config.ts:

import type { IntentsConfig } from 'react-native-ios-intents';

const config: IntentsConfig = {
  shortcuts: [
    {
      identifier: 'startTimer',
      title: 'Start Timer',
      phrases: ['Start timer', 'Begin tracking'],
      systemImageName: 'play.circle',
    },
  ],
};

export default config;

3. Configure iOS Capabilities

Open your project in Xcode and add the required capabilities:

  1. Siri (Recommended)

    • Select your target → Signing & Capabilities"+ Capability"Siri
  2. App Groups (Required)

    • "+ Capability"App Groups → click "+" to add a new group
    • Use format: group.{your.bundle.id} (e.g., group.com.myapp)
    • The library automatically uses group.{bundleId} — ensure it matches
  3. Add Generated Swift Files

    • Locate ios/{YourApp}/GeneratedAppIntents.swift
    • Drag it into your Xcode project, uncheck "Copy items if needed"
    • Ensure your app target is selected

See the iOS Setup Guide for more details.

4. Regenerate & Build

After editing your config, regenerate the Swift code and build:

npx react-native-ios-intents generate
npx react-native run-ios

5. Handle Invocations

import { useEffect } from 'react';
import { SiriShortcuts } from 'react-native-ios-intents';
import type { ShortcutInvocation } from './shortcuts.generated';

function App() {
  useEffect(() => {
    // Use generic type for full autocomplete support
    const subscription = SiriShortcuts.addEventListener<ShortcutInvocation>('shortcut', (shortcut, respond) => {
      // TypeScript now knows all possible identifiers!
      if (shortcut.identifier === 'startTimer') {
        // Handle state-based confirmations with userConfirmed
        if (shortcut.userConfirmed) {
          // User confirmed to override existing timer
          stopCurrentTimer();
          startNewTimer();
          respond({ message: "New timer started!" });
        } else {
          // Normal start
          startTimer();
          respond({ message: "Timer started!" });
        }
      }
    });

    return () => subscription.remove();
  }, []);

  return <YourApp />;
}

Now say "Hey Siri, start timer in [Your App Name]" and Siri will respond with your message!

Example App

The example/ directory contains a complete timer app demonstrating Siri Shortcuts with parameters, state dialogs, and Live Activities.

npm install
cd example && npm install && cd ios && pod install && cd ../..
npm run nitrogen
npm run generate-shortcuts:example
npm run example ios

API Reference

SiriShortcuts.addEventListener<T>(event, listener)

Listen for Siri shortcut invocations with optional type safety.

// Basic usage (default types)
const subscription = SiriShortcuts.addEventListener('shortcut', (shortcut, respond) => {
  // shortcut.identifier is string
  // shortcut.parameters is Record<string, any>
  // shortcut.userConfirmed is boolean | undefined
});

// Type-safe usage with generated types (recommended)
import type { ShortcutInvocation } from './shortcuts.generated';

const subscription = SiriShortcuts.addEventListener<ShortcutInvocation>('shortcut', (shortcut, respond) => {
  // TypeScript knows exact shortcut identifiers: 'startTimer' | 'stopTimer' | ...

  if (shortcut.identifier === 'addTask') {
    // TypeScript knows shortcut.parameters.taskName exists and is a string
    console.log(shortcut.parameters.taskName);
  }

  // Check if user confirmed a state dialog
  if (shortcut.userConfirmed === true) {
    // User confirmed an override dialog
  } else if (shortcut.userConfirmed === false) {
    // User cancelled (though handler typically won't receive this)
  } else {
    // No confirmation dialog was shown
  }

  respond({ message: "Done!" });
});

subscription.remove(); // cleanup

SiriShortcuts.updateAppState(state)

Sync app state for state-based dialogs.

SiriShortcuts.updateAppState({
  timerRunning: true,
  taskName: 'Work',
});

SiriShortcuts.cleanup(stateKeys?)

Full cleanup for logout/teardown scenarios.

// Full cleanup - remove listeners and clear all tracked app state
SiriShortcuts.cleanup();

// Clear only specific keys
SiriShortcuts.cleanup(['timerRunning', 'taskName']);

LiveActivities

import { LiveActivities } from 'react-native-ios-intents';

// Start — returns an activity ID
const id = LiveActivities.startActivity('timerActivity', { taskName: 'Work' }, { timerStart: new Date(), isRunning: true });

// Update content state
LiveActivities.updateActivity(id, 'timerActivity', { isRunning: false });

// End
LiveActivities.endActivity(id, 'timerActivity');

// Get running activities (useful for cleanup on app restart)
const running = LiveActivities.getRunningActivities();
// Returns: { activityId: string, activityType: string }[]

// Listen for button taps on Live Activity
const sub = LiveActivities.addEventListener('button', (action) => {
  console.log(action.identifier); // e.g. 'pauseTimer'
});
sub.remove();

See Live Activities documentation for configuration, layout nodes, and setup details.

Shortcut Parameters

Capture voice input from users through Siri:

Supported types: string, number, boolean, date

// intents.config.ts
{
  identifier: 'addTask',
  title: 'Add Task',
  phrases: ['Add a task', 'Create a task'],
  parameters: [
    { name: 'taskName', title: 'Task Name', type: 'string', optional: false },
    { name: 'dueDate', title: 'Due Date', type: 'date', optional: true }
  ]
}

Handling in your code:

import type { ShortcutInvocation } from './shortcuts.generated';

SiriShortcuts.addEventListener<ShortcutInvocation>('shortcut', (shortcut, respond) => {
  if (shortcut.identifier === 'addTask') {
    // TypeScript knows shortcut.parameters.taskName is a string
    const taskName = shortcut.parameters.taskName;
    const dueDate = shortcut.parameters.dueDate; // Date | undefined

    addTask(taskName, dueDate);
    respond({ message: `Task "${taskName}" added!` });
  }
});

See Configuration for more options and details.

Live Activities

Config-driven Live Activities for iOS 16.2+. Define your layout in intents.config.ts and the library generates SwiftUI views, ActivityAttributes, and the Widget Bundle.

const config: IntentsConfig = {
  shortcuts: [...],
  liveActivities: [{
    identifier: 'timerActivity',
    attributes: { taskName: { type: 'string', title: 'Task Name' } },
    contentState: {
      timerStart: { type: 'date', title: 'Timer Start' },
      isRunning: { type: 'boolean', title: 'Running' }
    },
    lockScreenLayout: {
      type: 'hstack',
      children: [
        { type: 'text', value: '${taskName}', font: 'headline' },
        { type: 'spacer' },
        { type: 'timer', timerStartField: 'timerStart', font: 'title', monospacedDigit: true }
      ]
    }
  }]
};

See Live Activities documentation for timer display, interactive buttons, conditional visibility, widget extension setup, and more.

Documentation

Contributing

We welcome contributions! See CONTRIBUTING.md for development setup, code generation workflow, and architecture details.

Known Issues

State Dialog API Uses Deprecated Confirmation Method

The current state dialog feature with requiresConfirmation: true uses requestConfirmation(result:) which is deprecated in iOS 16+. The code works but shows compiler warnings.

TODO: Update to modern App Intents confirmation flow using:

  • @Parameter for confirmation values
  • Proper IntentConfirmation structure

See: Apple App Intents Documentation - Confirmation

License

MIT


Made with create-react-native-library