@capgo/capacitor-live-activities

June 16, 2026 · View on GitHub

Capgo - Instant updates for Capacitor

➡️ Get Instant updates for your App with Capgo

Missing a feature? We'll build the plugin for you 💪

Manage iOS Live Activities from Capacitor with a powerful JSON-based layout system.

Why Capacitor Live Activities?

  • iOS 16.1+ Live Activities - Full integration with Apple's Live Activities framework
  • Dynamic Island Support - Seamless integration with iPhone 14 Pro+ Dynamic Island
  • JSON Layout System - Build complex layouts declaratively without Swift code
  • Real-time Updates - Update your activities dynamically from your app
  • Image Management - Save and use images in your Live Activities via App Groups
  • Cross-platform Safe - Graceful fallbacks on Android and web

Essential for delivery tracking apps, sports scores, ride-sharing, timers, and any app needing real-time lock screen updates.

Documentation

The most complete doc is available here: https://capgo.app/docs/plugins/live-activities/

Compatibility

Plugin versionCapacitor compatibilityMaintained
v8.*.*v8.*.*
v7.*.*v7.*.*On demand
v6.*.*v6.*.*
v5.*.*v5.*.*

Note: The major version of this plugin follows the major version of Capacitor. Use the version that matches your Capacitor installation (e.g., plugin v8 for Capacitor 8). Only the latest major version is actively maintained.

Install

You can use our AI-Assisted Setup to install the plugin. Add the Capgo skills to your AI tool using the following command:

npx skills add https://github.com/cap-go/capacitor-skills --skill capacitor-plugins

Then use the following prompt:

Use the `capacitor-plugins` skill from `cap-go/capacitor-skills` to install the `@capgo/capacitor-live-activities` plugin in my project.

If you prefer Manual Setup, install the plugin by running the following commands and follow the platform-specific instructions below:

bun add @capgo/capacitor-live-activities
bunx cap sync

Requirements

  • iOS 16.1+ - Live Activities require iOS 16.1 or later
  • Widget Extension - You must create a Widget Extension target in Xcode
  • App Groups - Required for sharing data between app and widget

iOS Setup

1. Create Widget Extension

In Xcode:

  1. File → New → Target
  2. Select "Widget Extension"
  3. Name it exactly: LiveActivities
  4. Uncheck "Include Configuration Intent"

2. Configure App Groups

  1. Select your main app target → Signing & Capabilities
  2. Add "App Groups" capability
  3. Create group: group.YOUR_BUNDLE_ID.liveactivities
  4. Add the same App Group to your Widget Extension target

3. Enable Live Activities in Info.plist

Add to your app's Info.plist:

<key>NSSupportsLiveActivities</key>
<true/>

4. Create the Widget Bundle

In your Widget Extension, create LiveActivitiesBundle.swift:

import WidgetKit
import SwiftUI

@main
struct LiveActivitiesBundle: WidgetBundle {
    var body: some Widget {
        // Your Live Activity widget goes here
        LiveActivityWidget()
    }
}

Usage Examples

Check Support

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';

const checkSupport = async () => {
  const { supported, reason } = await CapgoLiveActivities.areActivitiesSupported();
  if (supported) {
    console.log('Live Activities are supported!');
  } else {
    console.log('Not supported:', reason);
  }
};

Start a Delivery Tracking Activity

import { CapgoLiveActivities } from '@capgo/capacitor-live-activities';

const startDeliveryActivity = async () => {
  const { activityId } = await CapgoLiveActivities.startActivity({
    layout: {
      type: 'container',
      direction: 'vertical',
      spacing: 8,
      children: [
        {
          type: 'container',
          direction: 'horizontal',
          children: [
            { type: 'image', source: 'sfSymbol', value: 'box.truck.fill', width: 24, height: 24, tintColor: '#007AFF' },
            { type: 'text', content: 'Order #{{orderNumber}}', fontSize: 16, fontWeight: 'bold' }
          ]
        },
        { type: 'text', content: '{{status}}', fontSize: 14, color: '#666666' },
        { type: 'progress', value: 'progress', tint: '#34C759' }
      ]
    },
    dynamicIslandLayout: {
      expanded: {
        leading: { type: 'image', source: 'sfSymbol', value: 'box.truck.fill', tintColor: '#007AFF' },
        trailing: { type: 'text', content: '{{eta}}', fontWeight: 'semibold' },
        center: { type: 'text', content: '{{status}}', fontSize: 14 },
        bottom: { type: 'progress', value: 'progress', tint: '#34C759' }
      },
      compactLeading: { type: 'image', source: 'sfSymbol', value: 'box.truck.fill' },
      compactTrailing: { type: 'text', content: '{{eta}}' },
      minimal: { type: 'image', source: 'sfSymbol', value: 'box.truck.fill' }
    },
    behavior: {
      widgetUrl: 'myapp://order/12345'
    },
    data: {
      orderNumber: '12345',
      status: 'On the way',
      eta: '10 min',
      progress: 0.6
    }
  });

  console.log('Started activity:', activityId);
  return activityId;
};

Update an Activity

const updateActivity = async (activityId: string) => {
  await CapgoLiveActivities.updateActivity({
    activityId,
    data: {
      status: 'Arriving soon!',
      eta: '2 min',
      progress: 0.9
    },
    alertConfiguration: {
      title: 'Delivery Update',
      body: 'Your order is almost there!'
    }
  });
};

End an Activity

const endActivity = async (activityId: string) => {
  await CapgoLiveActivities.endActivity({
    activityId,
    data: {
      status: 'Delivered!',
      progress: 1.0
    },
    dismissalPolicy: 'after',
    dismissAfter: Date.now() + 3600000 // Keep visible for 1 hour
  });
};

Timer Example (Countdown)

const startTimerActivity = async () => {
  const targetDate = Date.now() + 1800000; // 30 minutes from now

  const { activityId } = await CapgoLiveActivities.startActivity({
    layout: {
      type: 'container',
      direction: 'horizontal',
      spacing: 16,
      children: [
        { type: 'image', source: 'sfSymbol', value: 'timer', width: 32, height: 32 },
        {
          type: 'container',
          direction: 'vertical',
          children: [
            { type: 'text', content: '{{title}}', fontSize: 16, fontWeight: 'bold' },
            { type: 'timer', targetDate: 'endTime', style: 'timer', fontSize: 24, fontWeight: 'bold', color: '#FF3B30' }
          ]
        }
      ]
    },
    dynamicIslandLayout: {
      expanded: {
        center: { type: 'text', content: '{{title}}' },
        bottom: { type: 'timer', targetDate: 'endTime', style: 'timer', fontSize: 32 }
      },
      compactLeading: { type: 'image', source: 'sfSymbol', value: 'timer' },
      compactTrailing: { type: 'timer', targetDate: 'endTime', style: 'timer' },
      minimal: { type: 'timer', targetDate: 'endTime', style: 'timer' }
    },
    data: {
      title: 'Cooking Timer',
      endTime: targetDate
    }
  });

  return activityId;
};

Using Saved Images

// Save an image first
const { imageName } = await CapgoLiveActivities.saveImage({
  imageData: 'base64EncodedImageData...',
  name: 'product-thumbnail',
  compressionQuality: 0.8
});

// Use in activity layout
const { activityId } = await CapgoLiveActivities.startActivity({
  layout: {
    type: 'container',
    direction: 'horizontal',
    children: [
      { type: 'image', source: 'saved', value: imageName, width: 48, height: 48, properties: { cornerRadius: 8 } },
      { type: 'text', content: '{{productName}}', fontSize: 16 }
    ]
  },
  // ... rest of config
});

// Cleanup when done
await CapgoLiveActivities.cleanupImages();

Layout Elements

Container

Groups child elements horizontally, vertically, or stacked.

{
  type: 'container',
  direction: 'horizontal' | 'vertical' | 'zstack',
  alignment: 'leading' | 'center' | 'trailing' | 'top' | 'bottom',
  spacing: 8,
  children: [/* ... */],
  properties: { padding: 12, backgroundColor: '#F5F5F5', cornerRadius: 8 }
}

Text

Displays text with styling and variable interpolation.

{
  type: 'text',
  content: 'Hello {{name}}!',
  fontSize: 16,
  fontWeight: 'bold',
  color: '#000000',
  alignment: 'center',
  lineLimit: 2,
  fontDesign: 'rounded'
}

Image

Displays images from various sources.

// SF Symbol
{ type: 'image', source: 'sfSymbol', value: 'star.fill', tintColor: '#FFD700' }

// URL
{ type: 'image', source: 'url', value: 'https://example.com/image.png', width: 48, height: 48 }

// Saved image
{ type: 'image', source: 'saved', value: 'my-saved-image' }

// Asset from bundle
{ type: 'image', source: 'asset', value: 'logo' }

Progress

Shows a progress bar.

{
  type: 'progress',
  value: 'progressValue', // Key in data object (0-1)
  tint: '#34C759'
}

Timer

Displays a countdown or elapsed time.

{
  type: 'timer',
  targetDate: 'endTime', // Key in data object (timestamp)
  style: 'timer' | 'relative' | 'offset',
  fontSize: 24,
  color: '#FF3B30',
  pausesOnReach: true
}

Gauge

Circular progress indicator.

{
  type: 'gauge',
  value: 'level', // Key in data (0-1)
  style: 'accessoryCircular',
  label: 'Battery',
  tint: '#34C759'
}

Spacer

Flexible space between elements.

{ type: 'spacer', minLength: 8 }

API

Capacitor Live Activities Plugin interface for managing iOS Live Activities.

areActivitiesSupported()

areActivitiesSupported() => Promise<AreActivitiesSupportedResult>

Check if Live Activities are supported on this device. Requires iOS 16.1+ and device support.

Returns: Promise<AreActivitiesSupportedResult>

Since: 1.0.0


startActivity(...)

startActivity(options: StartActivityOptions) => Promise<StartActivityResult>

Start a new Live Activity with the specified layout and data.

ParamTypeDescription
optionsStartActivityOptions- Options for starting the activity

Returns: Promise<StartActivityResult>

Since: 1.0.0


updateActivity(...)

updateActivity(options: UpdateActivityOptions) => Promise<void>

Update an existing Live Activity with new data.

ParamTypeDescription
optionsUpdateActivityOptions- Options for updating the activity

Since: 1.0.0


endActivity(...)

endActivity(options: EndActivityOptions) => Promise<void>

End a Live Activity.

ParamTypeDescription
optionsEndActivityOptions- Options for ending the activity

Since: 1.0.0


getAllActivities()

getAllActivities() => Promise<GetAllActivitiesResult>

Get all currently active Live Activities.

Returns: Promise<GetAllActivitiesResult>

Since: 1.0.0


saveImage(...)

saveImage(options: SaveImageOptions) => Promise<SaveImageResult>

Save an image to the shared App Group container for use in Live Activities. Images must be saved to the shared container to be accessible from the widget extension.

ParamTypeDescription
optionsSaveImageOptions- Options for saving the image

Returns: Promise<SaveImageResult>

Since: 1.0.0


removeImage(...)

removeImage(options: RemoveImageOptions) => Promise<RemoveImageResult>

Remove a saved image from the shared container.

ParamTypeDescription
optionsRemoveImageOptions- Options for removing the image

Returns: Promise<RemoveImageResult>

Since: 1.0.0


listImages()

listImages() => Promise<ListImagesResult>

List all saved images in the shared container.

Returns: Promise<ListImagesResult>

Since: 1.0.0


cleanupImages()

cleanupImages() => Promise<void>

Remove all saved images from the shared container.

Since: 1.0.0


getPluginVersion()

getPluginVersion() => Promise<{ version: string; }>

Get the native Capacitor plugin version.

Returns: Promise<{ version: string; }>

Since: 1.0.0


startTimerSequence(...)

startTimerSequence(options: TimerSequenceOptions) => Promise<TimerSequenceResult>

Start a timer sequence for workouts/sports. On iOS: Shows in Live Activity and Dynamic Island On Android: Shows as a foreground notification with timer

ParamTypeDescription
optionsTimerSequenceOptions- Timer sequence configuration

Returns: Promise<TimerSequenceResult>

Since: 1.0.0


pauseTimerSequence(...)

pauseTimerSequence(options: { sequenceId: string; }) => Promise<void>

Pause the timer sequence.

ParamTypeDescription
options{ sequenceId: string; }- Options containing the sequence ID

Since: 1.0.0


resumeTimerSequence(...)

resumeTimerSequence(options: { sequenceId: string; }) => Promise<void>

Resume a paused timer sequence.

ParamTypeDescription
options{ sequenceId: string; }- Options containing the sequence ID

Since: 1.0.0


stopTimerSequence(...)

stopTimerSequence(options: { sequenceId: string; }) => Promise<void>

Stop and dismiss the timer sequence.

ParamTypeDescription
options{ sequenceId: string; }- Options containing the sequence ID

Since: 1.0.0


skipTimerStep(...)

skipTimerStep(options: { sequenceId: string; }) => Promise<void>

Skip to the next step in the sequence.

ParamTypeDescription
options{ sequenceId: string; }- Options containing the sequence ID

Since: 1.0.0


previousTimerStep(...)

previousTimerStep(options: { sequenceId: string; }) => Promise<void>

Go back to the previous step in the sequence.

ParamTypeDescription
options{ sequenceId: string; }- Options containing the sequence ID

Since: 1.0.0


getTimerState(...)

getTimerState(options: GetTimerStateOptions) => Promise<TimerSequenceState>

Get the current state of a timer sequence.

ParamTypeDescription
optionsGetTimerStateOptions- Options containing the sequence ID

Returns: Promise<TimerSequenceState>

Since: 1.0.0


addListener('timerSequenceEvent', ...)

addListener(eventName: 'timerSequenceEvent', callback: TimerSequenceCallback) => Promise<{ remove: () => Promise<void>; }>

Add a listener for timer sequence events. Events include: stepChange, complete, tick, paused, resumed, stopped, loopComplete

ParamTypeDescription
eventName'timerSequenceEvent'- The event name to listen for
callbackTimerSequenceCallback- Callback function that receives the event

Returns: Promise<{ remove: () => Promise<void>; }>

Since: 1.0.0


Interfaces

AreActivitiesSupportedResult

Result of checking if activities are supported

PropTypeDescription
supportedbooleanWhether Live Activities are supported on this device
reasonstringReason if not supported

StartActivityResult

Result of starting an activity

PropTypeDescription
activityIdstringUnique activity identifier

StartActivityOptions

Options for starting a Live Activity

PropTypeDescription
layoutActivityLayoutMain activity layout (lock screen widget)
dynamicIslandLayoutDynamicIslandLayoutDynamic Island layout configuration
behaviorLiveActivitiesBehaviorActivity behavior settings
dataRecord<string, unknown>Dynamic data for the activity
staleDatenumberStale date timestamp (activity becomes stale after this)
relevanceScorenumberRelevance score for activity ordering (0-100)

LayoutElementContainer

Container layout element for grouping child elements

PropTypeDescription
type'container'
direction'horizontal' | 'vertical' | 'zstack'Layout direction
childrenLayoutElement[]Child elements
alignment'leading' | 'center' | 'trailing' | 'top' | 'bottom'Alignment within container
spacingnumberSpacing between children
propertiesBaseLayoutPropertiesContainer properties

BaseLayoutProperties

Base layout element properties

PropTypeDescription
paddingnumber | { top?: number; bottom?: number; leading?: number; trailing?: number; }Padding around the element
backgroundColorColorStringBackground color
cornerRadiusnumberCorner radius
widthnumber | 'infinity'Frame width
heightnumberFrame height
opacitynumberOpacity (0-1)

LayoutElementText

Text layout element

PropTypeDescription
type'text'
contentstringText content - supports {{variable}} interpolation
fontSizenumberFont size
fontWeight'ultraLight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black'Font weight
colorColorStringText color
alignment'leading' | 'center' | 'trailing'Text alignment
lineLimitnumberLine limit
fontDesign'default' | 'monospaced' | 'rounded' | 'serif'Font design
propertiesBaseLayoutPropertiesElement properties

LayoutElementImage

Image layout element

PropTypeDescription
type'image'
source'url' | 'sfSymbol' | 'asset' | 'base64' | 'saved'Image source type
valuestringImage value (URL, symbol name, asset name, base64 string, or saved image name)
widthnumberImage width
heightnumberImage height
contentMode'fit' | 'fill'Content mode
tintColorColorStringTint color for SF Symbols
propertiesBaseLayoutPropertiesElement properties

LayoutElementProgress

Progress bar layout element

PropTypeDescription
type'progress'
valuestring | numberProgress value key in data (0-1) or direct value
totalstring | numberTotal value key in data or direct value
tintColorStringProgress bar color
propertiesBaseLayoutPropertiesElement properties

LayoutElementTimer

Timer layout element for countdowns

PropTypeDescription
type'timer'
targetDatestring | numberTarget date key in data or timestamp
style'timer' | 'relative' | 'offset'Timer style
pausesOnReachbooleanPause when target reached
fontSizenumberFont size
colorColorStringText color
fontWeight'ultraLight' | 'thin' | 'light' | 'regular' | 'medium' | 'semibold' | 'bold' | 'heavy' | 'black'Font weight
propertiesBaseLayoutPropertiesElement properties

LayoutElementSpacer

Spacer layout element

PropTypeDescription
type'spacer'
minLengthnumberMinimum length

LayoutElementGauge

Gauge layout element for circular progress

PropTypeDescription
type'gauge'
valuestring | numberCurrent value key in data or direct value (0-1)
style'automatic' | 'accessoryCircular' | 'accessoryCircularCapacity' | 'linearCapacity'Gauge style
labelstringLabel text
currentValueLabelstringCurrent value label
minimumValueLabelstringMinimum value label
maximumValueLabelstringMaximum value label
tintColorStringTint color
propertiesBaseLayoutPropertiesElement properties

DynamicIslandLayout

Dynamic Island layout configuration

PropTypeDescription
expandedDynamicIslandExpandedLayoutExpanded state layout
compactLeadingLayoutElementCompact leading content
compactTrailingLayoutElementCompact trailing content
minimalLayoutElementMinimal presentation content

DynamicIslandExpandedLayout

Dynamic Island expanded layout configuration

PropTypeDescription
leadingLayoutElementLeading region content
trailingLayoutElementTrailing region content
centerLayoutElementCenter region content
bottomLayoutElementBottom region content

LiveActivitiesBehavior

Live Activity behavior configuration

PropTypeDescription
widgetUrlstringWidget URL for deep linking
backgroundTintColorStringBackground tint color
systemActionForegroundColorColorStringSystem action foreground color
keyLineTintColorStringKey line tint color

UpdateActivityOptions

Options for updating a Live Activity

PropTypeDescription
activityIdstringActivity ID to update
dataRecord<string, unknown>Updated data
alertConfigurationActivityAlertConfigurationOptional alert to show with update
staleDatenumberUpdated stale date
relevanceScorenumberUpdated relevance score

ActivityAlertConfiguration

Alert configuration for activity updates

PropTypeDescription
titlestringAlert title
bodystringAlert body
soundstringSound name (optional)

EndActivityOptions

Options for ending a Live Activity

PropTypeDescription
activityIdstringActivity ID to end
dataRecord<string, unknown>Final data to display
dismissalPolicy'default' | 'immediate' | 'after'Dismissal policy
dismissAfternumberDismiss after timestamp (when dismissalPolicy is 'after')

GetAllActivitiesResult

Result of getAllActivities

PropTypeDescription
activitiesActivityInfo[]List of activities

ActivityInfo

Activity info returned from getAllActivities

PropTypeDescription
activityIdstringActivity ID
state'active' | 'ended' | 'dismissed' | 'stale'Current activity state
startDatenumberActivity start date
dataRecord<string, unknown>Current data

SaveImageResult

Result of saving an image

PropTypeDescription
successbooleanWhether the save was successful
imageNamestringSaved image name

SaveImageOptions

Options for saving an image

PropTypeDescription
imageDatastringBase64 encoded image data
namestringName to save the image as
compressionQualitynumberJPEG compression quality (0-1, default 0.8)

RemoveImageResult

Result of removing an image

PropTypeDescription
successbooleanWhether the removal was successful

RemoveImageOptions

Options for removing an image

PropTypeDescription
namestringName of the image to remove

ListImagesResult

Result of listing images

PropTypeDescription
imagesstring[]List of saved image names

TimerSequenceResult

Result of starting a timer sequence

PropTypeDescription
sequenceIdstringUnique sequence identifier

TimerSequenceOptions

Options for starting a timer sequence

PropTypeDescription
stepsTimerStep[]Array of steps in the sequence
titlestringOverall title for the sequence (e.g., "HIIT Workout", "Tabata")
loopbooleanWhether to loop the sequence when complete
loopCountnumberNumber of times to loop (if loop is true, 0 means infinite)
soundEnabledbooleanPlay sound on step change (default: true)
vibrateEnabledbooleanVibrate on step change (default: true)
countdownBeepsbooleanPlay countdown beeps in last 3 seconds (default: true)
tapUrlstringDeep link URL when tapping the notification/activity
keepScreenOnbooleanKeep screen on during timer (Android only, default: false)

TimerStep

A single step in a timer sequence (e.g., workout interval)

PropTypeDescription
durationnumberDuration of this step in seconds
titlestringTitle/instruction for this step (e.g., "Push-ups", "Rest")
subtitlestringOptional subtitle (e.g., "20 reps", "High intensity")
colorstringColor for this step (hex color, e.g., "#FF0000" for work, "#00FF00" for rest)
iconstringOptional icon (SF Symbol name on iOS, material icon name on Android)
sound'beep' | 'bell' | 'whistle' | 'countdown' | 'none'Optional sound to play when step starts

TimerSequenceState

Current state of a timer sequence

PropTypeDescription
sequenceIdstringSequence ID
isRunningbooleanWhether the sequence is running
isPausedbooleanWhether the sequence is paused
isCompletebooleanWhether the sequence is complete
currentStepIndexnumberCurrent step index (0-based)
totalStepsnumberTotal number of steps
currentStepTimerStepCurrent step info
remainingSecondsnumberRemaining seconds in current step
totalRemainingSecondsnumberTotal remaining seconds for entire sequence
elapsedSecondsnumberTotal elapsed seconds
currentLoopnumberCurrent loop iteration (1-based, if looping)
totalLoopsnumberTotal loops (0 if infinite or not looping)

GetTimerStateOptions

Options for getting timer state

PropTypeDescription
sequenceIdstringSequence ID to get state for

TimerSequenceEvent

Event data for timer sequence events

PropTypeDescription
type'stepChange' | 'complete' | 'tick' | 'paused' | 'resumed' | 'stopped' | 'loopComplete'Event type
sequenceIdstringSequence ID
stateTimerSequenceStateCurrent state when event occurred

Type Aliases

ActivityLayout

Layout for the main activity view (lock screen widget)

LayoutElement

LayoutElement

Union type for all layout elements

LayoutElementContainer | LayoutElementText | LayoutElementImage | LayoutElementProgress | LayoutElementTimer | LayoutElementSpacer | LayoutElementGauge

ColorString

Color string type - supports hex colors and system colors

string

Record

Construct a type with a set of properties K of type T

{ [P in K]: T; }

TimerSequenceCallback

Callback type for timer sequence events

(event: TimerSequenceEvent): void

Credits

Inspired by ludufre/capacitor-live-activities with a simplified API and Capgo integration.