HomeGuidesReferenceLearn

Reference version

ArchiveExpo SnackDiscord and ForumsNewsletter

Expo Contacts iconExpo Contacts

GitHub

npm

A library that provides access to the phone's system contacts.


expo-contacts provides access to the device's system contacts, allowing you to get contact information as well as adding, editing, or removing contacts.

On iOS, contacts have a multi-layered grouping system that you can also access through this API.

Platform Compatibility

Android DeviceAndroid EmulatoriOS DeviceiOS SimulatorWeb

Installation

Terminal
npx expo install expo-contacts

If you're installing this in a bare React Native app, you should also follow these additional installation instructions.

Configuration in app.json/app.config.js

You can configure expo-contacts using its built-in config plugin if you use config plugins in your project (EAS Build or npx expo run:[android|ios]). The plugin allows you to configure various properties that cannot be set at runtime and require building a new app binary to take effect.

Example app.json with config plugin

app.json
{
  "expo": {
    "plugins": [
      [
        "expo-contacts",
        {
          "contactsPermission": "Allow $(PRODUCT_NAME) to access your contacts."
        }
      ]
    ]
  }
}

Configurable properties

NameDefaultDescription
contactsPermission"Allow $(PRODUCT_NAME) to access your contacts"Only for:
iOS

A string to set the NSContactsUsageDescription permission message.

Are you using this library in a bare React Native app?

Learn how to configure the native projects in the installation instructions in the expo-contacts repository.

Usage

Basic Contacts Usage
import React, { useEffect } from 'react';
import { StyleSheet, View, Text } from 'react-native';
import * as Contacts from 'expo-contacts';

export default function App() {
  useEffect(() => {
    (async () => {
      const { status } = await Contacts.requestPermissionsAsync();
      if (status === 'granted') {
        const { data } = await Contacts.getContactsAsync({
          fields: [Contacts.Fields.Emails],
        });

        if (data.length > 0) {
          const contact = data[0];
          console.log(contact);
        }
      }
    })();
  }, []);

  return (
    <View style={styles.container}>
      <Text>Contacts Module Example</Text>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

API

import * as Contacts from 'expo-contacts';

Methods

Contacts.addContactAsync(contact, containerId)

NameTypeDescription
contactContact

A contact with the changes you wish to persist. The id parameter will not be used.

containerId
(optional)
stringOnly for: 
iOS

The container that will parent the contact.


Creates a new contact and adds it to the system.

Note: For Android users, the Expo Go app does not have the required WRITE_CONTACTS permission to write to Contacts. You will need to create a development build and add permission in there manually to use this method.

Example

const contact = {
  [Contacts.Fields.FirstName]: 'Bird',
  [Contacts.Fields.LastName]: 'Man',
  [Contacts.Fields.Company]: 'Young Money',
};
const contactId = await Contacts.addContactAsync(contact);

Returns

  • Promise<string>

A promise that fulfills with ID of the new system contact.

Only for:
iOS

Contacts.addExistingContactToGroupAsync(contactId, groupId)

NameTypeDescription
contactIdstring

ID of the contact you want to edit.

groupIdstring

ID for the group you want to add membership to.


Add a contact as a member to a group. A contact can be a member of multiple groups.

Example

await Contacts.addExistingContactToGroupAsync(
  '665FDBCFAE55-D614-4A15-8DC6-161A368D',
  '161A368D-D614-4A15-8DC6-665FDBCFAE55'
);

Returns

  • Promise<any>

Only for:
iOS

Contacts.addExistingGroupToContainerAsync(groupId, containerId)

NameTypeDescription
groupIdstring

The group you want to target.

containerIdstring

The container you want to add membership to.


Add a group to a container.

Example

await Contacts.addExistingGroupToContainerAsync(
  '161A368D-D614-4A15-8DC6-665FDBCFAE55',
  '665FDBCFAE55-D614-4A15-8DC6-161A368D'
);

Returns

  • Promise<any>

Only for:
iOS

Contacts.createGroupAsync(name, containerId)

NameTypeDescription
name
(optional)
string

Name of the new group.

containerId
(optional)
string

The container you to add membership to.


Create a group with a name, and add it to a container. If the container is undefined, the default container will be targeted.

Example

const groupId = await Contacts.createGroupAsync('Sailor Moon');

Returns

  • Promise<string>

A promise that fulfills with ID of the new group.

Contacts.getContactByIdAsync(id, fields)

NameTypeDescription
idstring

The ID of a system contact.

fields
(optional)
FieldType[]

If specified, the fields defined will be returned. When skipped, all fields will be returned.


Used for gathering precise data about a contact. Returns a contact matching the given id.

Example

const contact = await Contacts.getContactByIdAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');
if (contact) {
  console.log(contact);
}

Returns

  • Promise<Contact | undefined>

A promise that fulfills with Contact object with ID matching the input ID, or undefined if there is no match.

Contacts.getContactsAsync(contactQuery)

NameTypeDescription
contactQuery
(optional)
ContactQuery

Object used to query contacts.

Default: {}

Return a list of contacts that fit a given criteria. You can get all of the contacts by passing no criteria.

Example

const { data } = await Contacts.getContactsAsync({
  fields: [Contacts.Fields.Emails],
});

if (data.length > 0) {
  const contact = data[0];
  console.log(contact);
}

Returns

  • Promise<ContactResponse>

A promise that fulfills with ContactResponse object returned from the query.

Only for:
iOS

Contacts.getContainersAsync(containerQuery)

NameTypeDescription
containerQueryContainerQuery

Information used to gather containers.


Query a list of system containers.

Example

const allContainers = await Contacts.getContainersAsync({
  contactId: '665FDBCFAE55-D614-4A15-8DC6-161A368D',
});

Returns

  • Promise<Container[]>

A promise that fulfills with array of containers that fit the query.

Only for:
iOS

Contacts.getDefaultContainerIdAsync()

Get the default container's ID.

Example

const containerId = await Contacts.getDefaultContainerIdAsync();

Returns

  • Promise<string>

A promise that fulfills with default container ID.

Only for:
iOS

Contacts.getGroupsAsync(groupQuery)

NameTypeDescription
groupQueryGroupQuery

Information regarding which groups you want to get.


Query and return a list of system groups.

Example

const groups = await Contacts.getGroupsAsync({ groupName: 'sailor moon' });
const allGroups = await Contacts.getGroupsAsync({});

Returns

  • Promise<Group[]>

A promise that fulfills with array of groups that fit the query.

Contacts.getPagedContactsAsync(contactQuery)

NameTypeDescription
contactQuery
(optional)
ContactQuery-

Returns

  • Promise<ContactResponse>

Contacts.getPermissionsAsync()

Checks user's permissions for accessing contacts data.

Returns

  • Promise<PermissionResponse>

A promise that resolves to a PermissionResponse object.

Contacts.isAvailableAsync()

Returns whether the Contacts API is enabled on the current device. This method does not check the app permissions.

Returns

  • Promise<boolean>

A promise that fulfills with a boolean, indicating whether the Contacts API is available on the current device. It always resolves to false on web.

Contacts.presentFormAsync(contactId, contact, formOptions)

NameTypeDescription
contactId
(optional)
null | string

The ID of a system contact.

contact
(optional)
null | Contact

A contact with the changes you want to persist.

formOptions
(optional)
FormOptions

Options for the native editor.

Default: {}

Present a native form for manipulating contacts.

Example

await Contacts.presentFormAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');

Returns

  • Promise<any>

Only for:
iOS

Contacts.removeContactAsync(contactId)

NameTypeDescription
contactIdstring

ID of the contact you want to delete.


Delete a contact from the system.

Example

await Contacts.removeContactAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');

Returns

  • Promise<any>

Only for:
iOS

Contacts.removeContactFromGroupAsync(contactId, groupId)

NameTypeDescription
contactIdstring

ID of the contact you want to remove.

groupIdstring

ID for the group you want to remove membership of.


Remove a contact's membership from a given group. This will not delete the contact.

Example

await Contacts.removeContactFromGroupAsync(
  '665FDBCFAE55-D614-4A15-8DC6-161A368D',
  '161A368D-D614-4A15-8DC6-665FDBCFAE55'
);

Returns

  • Promise<any>

Only for:
iOS

Contacts.removeGroupAsync(groupId)

NameTypeDescription
groupIdstring

ID of the group you want to remove.


Delete a group from the device.

Example

await Contacts.removeGroupAsync('161A368D-D614-4A15-8DC6-665FDBCFAE55');

Returns

  • Promise<any>

Contacts.requestPermissionsAsync()

Asks the user to grant permissions for accessing contacts data.

Returns

  • Promise<PermissionResponse>

A promise that resolves to a PermissionResponse object.

Contacts.shareContactAsync(contactId, message, shareOptions)

NameTypeDescription
contactIdstring-
messagestring-
shareOptions
(optional)
object-

Returns

  • Promise<any>

Only for:
iOS

Contacts.updateContactAsync(contact)

NameTypeDescription
contactContact

A contact object including the wanted changes.


Mutate the information of an existing contact. Due to an iOS bug, nonGregorianBirthday field cannot be modified.

On Android, you can use presentFormAsync to make edits to contacts.

Example

const contact = {
  id: '161A368D-D614-4A15-8DC6-665FDBCFAE55',
  [Contacts.Fields.FirstName]: 'Drake',
  [Contacts.Fields.Company]: 'Young Money',
};
await Contacts.updateContactAsync(contact);

Returns

  • Promise<string>

A promise that fulfills with ID of the updated system contact if mutation was successful.

Only for:
iOS

Contacts.updateGroupNameAsync(groupName, groupId)

NameTypeDescription
groupNamestring

New name for an existing group.

groupIdstring

ID of the group you want to edit.


Change the name of an existing group.

Example

await Contacts.updateGroupName('Expo Friends', '161A368D-D614-4A15-8DC6-665FDBCFAE55');

Returns

  • Promise<any>

Contacts.writeContactToFileAsync(contactQuery)

NameTypeDescription
contactQuery
(optional)
ContactQuery

Used to query contact you want to write.

Default: {}

Query a set of contacts and write them to a local URI that can be used for sharing.

Example

const localUri = await Contacts.writeContactToFileAsync({
  id: '161A368D-D614-4A15-8DC6-665FDBCFAE55',
});
Share.share({ url: localUri, message: 'Call me!' });

Returns

  • Promise<string | undefined>

A promise that fulfills with shareable local URI, or undefined if there was no match.

Interfaces

PermissionResponse

An object obtained by permissions get and request functions.

PermissionResponse Properties

NameTypeDescription
canAskAgainboolean

Indicates if user can be asked again for specific permission. If not, one should be directed to the Settings app in order to enable/disable the permission.

expiresPermissionExpiration

Determines time when the permission expires.

grantedboolean

A convenience boolean that indicates if the permission is granted.

statusPermissionStatus

Determines the status of the permission.


Types

Address

NameTypeDescription
city
(optional)
string

City name.

country
(optional)
string

Country name

id
(optional)
string

Unique ID. This value will be generated by the OS.

isoCountryCode
(optional)
string

Standard country code.

labelstring

Localized display name.

neighborhood
(optional)
string

Neighborhood name.

poBox
(optional)
string

P.O. Box.

postalCode
(optional)
string

Local post code.

region
(optional)
string

Region or state name.

street
(optional)
string

Street name.

CalendarFormatType

Literal Type: multiple types

Acceptable values are: CalendarFormats

Contact

A set of fields that define information about a single contact entity.

NameTypeDescription
addresses
(optional)
Address[]

Locations.

birthday
(optional)
Date

Birthday information in Gregorian format.

company
(optional)
string

Organization the entity belongs to.

contactTypeContactType

Denoting a person or company.

dates
(optional)
Date[]

A labeled list of other relevant user dates in Gregorian format.

department
(optional)
string

Job department.

emails
(optional)
Email[]

Email addresses.

firstName
(optional)
string

Given name.

id
(optional)
string

Immutable identifier used for querying and indexing. This value will be generated by the OS when the contact is created.

image
(optional)
Image

Thumbnail image. On iOS it size is set to 320×320px, on Android it may vary.

imageAvailable
(optional)
boolean

Used for efficient retrieval of images.

instantMessageAddresses
(optional)
InstantMessageAddress[]

Instant messaging connections.

jobTitle
(optional)
string

Job description.

lastName
(optional)
string

Last name.

maidenName
(optional)
string

Maiden name.

middleName
(optional)
string

Middle name

namestring

Full name with proper format.

namePrefix
(optional)
string

Dr. Mr. Mrs. ect…

nameSuffix
(optional)
string

Jr. Sr. ect…

nickname
(optional)
string

An alias to the proper name.

nonGregorianBirthday
(optional)
DateOnly for:
iOS

Birthday that doesn't conform to the Gregorian calendar format, interpreted based on the calendar format setting.

note
(optional)
string

Additional information.

On iOS 13+, the note field requires your app to request additional entitlements. The Expo Go app does not contain those entitlements, so in order to test this feature you will need to request the entitlement from Apple, set the ios.accessesContactNotes field in app config to true, and create your development build.

phoneNumbers
(optional)
PhoneNumber[]

Phone numbers.

phoneticFirstName
(optional)
string

Pronunciation of the first name.

phoneticLastName
(optional)
string

Pronunciation of the last name.

phoneticMiddleName
(optional)
string

Pronunciation of the middle name.

rawImage
(optional)
Image

Raw image without cropping, usually large.

relationships
(optional)
Relationship[]

Names of other relevant user connections.

socialProfiles
(optional)
SocialProfile[]Only for:
iOS

Social networks.

urlAddresses
(optional)
UrlAddress[]

Associated web URLs.

ContactQuery

Used to query contacts from the user's device.

NameTypeDescription
containerId
(optional)
stringOnly for:
iOS

Get all contacts that belong to the container matching this ID.

fields
(optional)
FieldType[]

If specified, the defined fields will be returned. If skipped, all fields will be returned.

groupId
(optional)
stringOnly for:
iOS

Get all contacts that belong to the group matching this ID.

id
(optional)
string | string[]

Get contacts with a matching ID or array of IDs.

name
(optional)
string

Get all contacts whose name contains the provided string (not case-sensitive).

pageOffset
(optional)
number

The number of contacts to skip before gathering contacts.

pageSize
(optional)
number

The max number of contacts to return. If skipped or set to 0 all contacts will be returned.

rawContacts
(optional)
booleanOnly for:
iOS

Prevent unification of contacts when gathering.

Default: false
sort
(optional)
ContactSort

Sort method used when gathering contacts.

ContactResponse

The return value for queried contact operations like getContactsAsync.

NameTypeDescription
dataContact[]

An array of contacts that match a particular query.

hasNextPageboolean

This will be true if there are more contacts to retrieve beyond what is returned.

hasPreviousPageboolean

This will be true if there are previous contacts that weren't retrieved due to pageOffset` limit.

ContactType

Literal Type: multiple types

Acceptable values are: ContactTypes

Container

NameTypeDescription
idstring-
namestring-
typeContainerType-
Only for:
iOS

ContainerQuery

Used to query native contact containers.

NameTypeDescription
contactId
(optional)
string

Query all the containers that parent a contact.

containerId
(optional)
string | string[]

Query all the containers that matches ID or an array od IDs.

groupId
(optional)
string

Query all the containers that parent a group.

ContainerType

Literal Type: multiple types

Acceptable values are: ContainerTypes

Date

NameTypeDescription
day
(optional)
number

Day.

format
(optional)
CalendarFormatType

Format for the input date.

id
(optional)
string

Unique ID. This value will be generated by the OS.

labelstring

Localized display name.

month
(optional)
number

Month - adjusted for JavaScript Date which starts at 0.

year
(optional)
number

Year.

Email

NameTypeDescription
email
(optional)
string

Email address.

id
(optional)
string

Unique ID. This value will be generated by the OS.

isPrimary
(optional)
boolean

Flag signifying if it is a primary email address.

labelstring

Localized display name.

FieldType

Literal Type: multiple types

Acceptable values are: Fields

FormOptions

Denotes the functionality of a native contact form.

NameTypeDescription
allowsActions
(optional)
boolean

Actions like share, add, create.

allowsEditing
(optional)
boolean

Allows for contact mutation.

alternateName
(optional)
string

Used if contact doesn't have a name defined.

cancelButtonTitle
(optional)
string

The name of the left bar button.

displayedPropertyKeys
(optional)
FieldType[]

The properties that will be displayed. On iOS those properties does nothing while in editing mode.

groupId
(optional)
string

The parent group for a new contact.

isNew
(optional)
boolean

Present the new contact controller. If set to false the unknown controller will be shown.

message
(optional)
string

Controller title.

preventAnimation
(optional)
boolean

Prevents the controller from animating in.

shouldShowLinkedContacts
(optional)
boolean

Show or hide the similar contacts.

Only for:
iOS

Group

A parent to contacts. A contact can belong to multiple groups. Here are some query operations you can perform:

  • Child Contacts: getContactsAsync({ groupId })
  • Groups From Container: getGroupsAsync({ containerId })
  • Groups Named: getContainersAsync({ groupName })
NameTypeDescription
id
(optional)
string

The editable name of a group.

name
(optional)
string

Immutable id representing the group.

Only for:
iOS

GroupQuery

Used to query native contact groups.

NameTypeDescription
containerId
(optional)
string

Query all groups that belong to a certain container.

groupId
(optional)
string

Query the group with a matching ID.

groupName
(optional)
string

Query all groups matching a name.

Image

Information regarding thumbnail images.

On Android you can get dimensions using Image.getSize method.

NameTypeDescription
base64
(optional)
string

Image as Base64 string.

height
(optional)
numberOnly for:
iOS

Image height

uri
(optional)
string

A local image URI.

Note: If you have a remote URI, download it first using FileSystem.downloadAsync.

width
(optional)
numberOnly for:
iOS

Image width.

InstantMessageAddress

NameTypeDescription
id
(optional)
string

Unique ID. This value will be generated by the OS.

labelstring

Localized display name.

localizedService
(optional)
string

Localized name of app.

service
(optional)
string

Name of instant messaging app.

username
(optional)
string

Username in IM app.

PhoneNumber

NameTypeDescription
countryCode
(optional)
string

Country code.

Example

+1

digits
(optional)
string

Phone number without format.

Example

8674305

id
(optional)
string

Unique ID. This value will be generated by the OS.

isPrimary
(optional)
boolean

Flag signifying if it is a primary phone number.

labelstring

Localized display name.

number
(optional)
string

Phone number.

Relationship

NameTypeDescription
id
(optional)
string

Unique ID. This value will be generated by the OS.

labelstring

Localized display name.

name
(optional)
string

Name of related contact.

Only for:
iOS

SocialProfile

NameTypeDescription
id
(optional)
string

Unique ID. This value will be generated by the OS.

labelstring

Localized display name.

localizedProfile
(optional)
string

Localized profile name.

service
(optional)
string

Name of social app.

url
(optional)
string

Web URL.

userId
(optional)
string

Username ID in social app.

username
(optional)
string

Username in social app.

UrlAddress

NameTypeDescription
id
(optional)
string

Unique ID. This value will be generated by the OS.

labelstring

Localized display name.

url
(optional)
string

Web URL.

Enums

CalendarFormats

This format denotes the common calendar format used to specify how a date is calculated in nonGregorianBirthday fields.

CalendarFormats Values

Only for:
iOS

Buddhist

CalendarFormats.Buddhist = "buddhist"
Only for:
iOS

Chinese

CalendarFormats.Chinese = "chinese"
Only for:
iOS

Coptic

CalendarFormats.Coptic = "coptic"
Only for:
iOS

EthiopicAmeteAlem

CalendarFormats.EthiopicAmeteAlem = "ethiopicAmeteAlem"
Only for:
iOS

EthiopicAmeteMihret

CalendarFormats.EthiopicAmeteMihret = "ethiopicAmeteMihret"

Gregorian

CalendarFormats.Gregorian = "gregorian"
Only for:
iOS

Hebrew

CalendarFormats.Hebrew = "hebrew"
Only for:
iOS

Indian

CalendarFormats.Indian = "indian"
Only for:
iOS

Islamic

CalendarFormats.Islamic = "islamic"
Only for:
iOS

IslamicCivil

CalendarFormats.IslamicCivil = "islamicCivil"
Only for:
iOS

IslamicTabular

CalendarFormats.IslamicTabular = "islamicTabular"
Only for:
iOS

IslamicUmmAlQura

CalendarFormats.IslamicUmmAlQura = "islamicUmmAlQura"
Only for:
iOS

ISO8601

CalendarFormats.ISO8601 = "iso8601"
Only for:
iOS

Japanese

CalendarFormats.Japanese = "japanese"
Only for:
iOS

Persian

CalendarFormats.Persian = "persian"
Only for:
iOS

RepublicOfChina

CalendarFormats.RepublicOfChina = "republicOfChina"

ContactTypes

ContactTypes Values

Company

ContactTypes.Company = "company"

Contact is group or company.

Person

ContactTypes.Person = "person"

Contact is a human.

Only for:
iOS

ContainerTypes

ContainerTypes Values

CardDAV

ContainerTypes.CardDAV = "cardDAV"

With cardDAV protocol used for sharing.

Exchange

ContainerTypes.Exchange = "exchange"

In association with email server.

Local

ContainerTypes.Local = "local"

A local non-iCloud container.

Unassigned

ContainerTypes.Unassigned = "unassigned"

Unknown container.

Fields

Possible fields to retrieve for a contact.

Fields Values

Addresses

Fields.Addresses = "addresses"

Birthday

Fields.Birthday = "birthday"

Company

Fields.Company = "company"

ContactType

Fields.ContactType = "contactType"

Dates

Fields.Dates = "dates"

Department

Fields.Department = "department"

Emails

Fields.Emails = "emails"

ExtraNames

Fields.ExtraNames = "extraNames"

FirstName

Fields.FirstName = "firstName"

ID

Fields.ID = "id"

Image

Fields.Image = "image"

ImageAvailable

Fields.ImageAvailable = "imageAvailable"

InstantMessageAddresses

Fields.InstantMessageAddresses = "instantMessageAddresses"

JobTitle

Fields.JobTitle = "jobTitle"

LastName

Fields.LastName = "lastName"

MaidenName

Fields.MaidenName = "maidenName"

MiddleName

Fields.MiddleName = "middleName"

Name

Fields.Name = "name"

NamePrefix

Fields.NamePrefix = "namePrefix"

NameSuffix

Fields.NameSuffix = "nameSuffix"

Nickname

Fields.Nickname = "nickname"
Only for:
iOS

NonGregorianBirthday

Fields.NonGregorianBirthday = "nonGregorianBirthday"

Note

Fields.Note = "note"

PhoneNumbers

Fields.PhoneNumbers = "phoneNumbers"

PhoneticFirstName

Fields.PhoneticFirstName = "phoneticFirstName"

PhoneticLastName

Fields.PhoneticLastName = "phoneticLastName"

PhoneticMiddleName

Fields.PhoneticMiddleName = "phoneticMiddleName"

RawImage

Fields.RawImage = "rawImage"

Relationships

Fields.Relationships = "relationships"
Only for:
iOS

SocialProfiles

Fields.SocialProfiles = "socialProfiles"

UrlAddresses

Fields.UrlAddresses = "urlAddresses"

PermissionStatus

PermissionStatus Values

DENIED

PermissionStatus.DENIED = "denied"

User has denied the permission.

GRANTED

PermissionStatus.GRANTED = "granted"

User has granted the permission.

UNDETERMINED

PermissionStatus.UNDETERMINED = "undetermined"

User hasn't granted or denied the permission yet.

SortTypes

SortTypes Values

FirstName

SortTypes.FirstName = "firstName"

Sort by first name in ascending order.

LastName

SortTypes.LastName = "lastName"

Sort by last name in ascending order.

None

SortTypes.None = "none"

No sorting should be applied.

Only for:
Android

UserDefault

SortTypes.UserDefault = "userDefault"

The user default method of sorting.

Permissions

Android

You must add the following permissions to your app.json inside the expo.android.permissions array.

Android PermissionDescription

READ_CONTACTS

Allows an application to read the user's contacts data.

WRITE_CONTACTS

Allows an application to write the user's contacts data.

iOS

The following usage description keys are used by this library:

Info.plist KeyDescription

NSContactsUsageDescription

A message that tells the user why the app is requesting access to the user’s contacts.