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

@nikita-chabaniuk/expo-icloud-storage

v1.0.12

Published

Expo module for working with iCloud

Readme

Expo iCloud Storage

A lightweight Expo module that provides a typed JavaScript API for interacting with a user's iCloud Drive.
Use it to upload / download files, create directories, check file existence, and listen for real-time progress events – all without leaving the JavaScript world.


✨ Features

  • Works in managed and bare Expo or React Native projects (iOS 13+).
  • Promise-based API with TypeScript definitions out of the box.
  • Granular progress callbacks for batch upload and download operations.
  • Utility helpers for common path manipulations.

📦 Installation

# with npm
yarn add @oleg_svetlichnyi/expo-icloud-storage
# or npm
npm install @oleg_svetlichnyi/expo-icloud-storage --save

Expo managed workflow

Nothing else to do – the module will be autolinked at build time by the Expo SDK.

Bare React Native / Expo modules workflow

Ensure you have configured the Expo Modules API in your iOS project, then run pod install inside the ios directory.

🚨 iCloud capability – Open Xcode, select your target, Signing & Capabilities → add iCloud with "iCloud Drive" checked.


🍏 iOS configuration (app.json / app.config.js)

Expo needs the proper iCloud entitlements.
Add usesIcloudStorage and a NSUbiquitousContainers entry inside ios.infoPlist:

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSUbiquitousContainers": {
          "iCloud.$(CFBundleIdentifier)": {
            "NSUbiquitousContainerIsDocumentScopePublic": false,
            "NSUbiquitousContainerName": "$(PRODUCT_NAME)",
            "NSUbiquitousContainerSupportedFolderLevels": "Any"
          }
        }
      }
    }
  }
}

Replace the container identifier if you created a custom one in the Apple Developer portal.


🚀 Example

The snippet below brings together every export of the library so you can see them in action. It backs up a local SQLite DB to iCloud and restores it back.

import {
  defaultICloudContainerPath,
  isICloudAvailableAsync,
  createDirAsync,
  isExistAsync,
  readDirAsync,
  uploadFilesAsync,
  unlinkAsync,
  uploadFileAsync,
  downloadFileAsync,
  downloadFilesAsync,
  PathUtils,
  addUploadFilesAsyncProgressListener,
  addDownloadFilesAsyncProgressListener,
} from '@oleg_svetlichnyi/expo-icloud-storage';
import * as FileSystem from 'expo-file-system';

async function backupDatabase() {
  if (!(await isICloudAvailableAsync())) {
    console.warn('iCloud unavailable');
    return;
  }

  const containerDocs = `${defaultICloudContainerPath}/Documents`;
  const sqlDir = `${containerDocs}/SQL`;

  // Make sure destination folder exists
  if (!(await isExistAsync(sqlDir, true))) {
    await createDirAsync('SQL');
  }

  // Upload current DB file
  await uploadFileAsync({
    destinationPath: 'SQL/app-backup.db',
    filePath: FileSystem.documentDirectory + 'SQLite/app.db',
  });
}

async function listBackups() {
  const files = await readDirAsync('SQL');
  console.log('All backups', files);
}

async function restoreLatest() {
  const files = await readDirAsync('SQL', { isFullPath: false });
  if (!files.length) return;

  // take the first one (latest by your own sorting)
  const latest = files[0];
  const downloadPath = await downloadFileAsync(
    `${defaultICloudContainerPath}/Documents/SQL/${latest}`,
    FileSystem.documentDirectory + 'SQLite'
  );
  console.log('Restored to', downloadPath);
}

// Listen to progress when uploading multiple files
const sub = addUploadFilesAsyncProgressListener(({ value }) => console.log('Progress', value));

// Later → sub.remove();

Running the Example App

A full example Expo application is included in the example directory. To run it:

  1. Build the module first:

    # From the root directory
    npm run prepare
  2. Run the example:

    cd example
    npm install
    npm run ios

The example app demonstrates all the module's features with a simple UI.

Expo iCloud Storage Example App Screenshot


🔌 API Reference

| Method | Signature | Description | | ------ | --------- | ----------- | | defaultICloudContainerPath | string \| null | Absolute path to the app's iCloud container. null if iCloud is disabled. | | isICloudAvailableAsync() | Promise<boolean> | Detect whether the user is signed in to iCloud and the capability is enabled. | | isExistAsync(path, isDirectory) | Promise<boolean> | Check if a file or directory exists inside the container. | | createDirAsync(path) | Promise<void> | Recursively create a folder inside iCloud Drive. | | readDirAsync(path, { isFullPath? }) | Promise<string[]> | List directory contents. When isFullPath is false only file names are returned. | | uploadFileAsync({ destinationPath, filePath }) | Promise<void> | Upload a single local file (file://…) to iCloud. | | uploadFilesAsync({ destinationDirectory, filePaths }) | Promise<void> | Upload multiple files to the given directory. Progress events are emitted (see below). | | downloadFileAsync(path, destinationDir) | Promise<string> | Download a remote file; resolves with the local path once copied. | | downloadFilesAsync(paths, destinationDir) | Promise<Array<{ success: boolean; path: string }>> | Download an array of iCloud file paths at once. Emits progress events and returns the result for every file. | | unlinkAsync(path) | Promise<void> | Permanently remove a file or folder from iCloud Drive. |

Events

import {
  addUploadFilesAsyncProgressListener,
  addDownloadFilesAsyncProgressListener,
} from '@oleg_svetlichnyi/expo-icloud-storage';

// value is a Double between 0 – 100
const sub = addUploadFilesAsyncProgressListener(({ value }) => {
  console.log('Upload progress', value);
});

// Remember to unsubscribe
sub.remove();

| Event listener | Emitted from | Payload | | -------------- | ------------ | ------- | | addUploadFilesAsyncProgressListener | uploadFile(s)Async | { value: number } percentage | | addDownloadFilesAsyncProgressListener | downloadFile(s)Async | { value: number } percentage |

Path utilities

import { PathUtils } from '@oleg_svetlichnyi/expo-icloud-storage';

PathUtils.ext('file.jpg.icloud');          // 'icloud' (last segment)
PathUtils.iCloudRemoveDotExt('photo.heic.icloud'); // 'photo.heic'

📄 License

MIT © 2024 — based on Expo Modules SDK