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

expo-downloads

v0.1.2

Published

An Expo module for downloading files directly to the native Downloads folder on Android and iOS.

Downloads

64

Readme

expo-downloads

An Expo module for directly downloading files to the native Downloads folder on Android and iOS.

Table of Contents

Installation

npx expo install expo-downloads

Usage

Below is a sample code which saves a text file named example.txt to the native Downloads folder. For Android versions 9 and below, the WRITE_EXTERNAL_STORAGE permission is checked.

import { saveFile, openFile, getPermissionsAsync, requestPermissionsAsync } from "expo-downloads";

const options = {
  name: "example.txt",
  type: "text/plain",
  data: "Hello, World!",
};

// For Android 9 and below, request WRITE_EXTERNAL_STORAGE permission.
const permissions = await getPermissionsAsync();
if (!permissions.granted) {
  const newPermissions = await requestPermissionsAsync();
  if (!newPermissions.granted) {
    console.error("Could not obtain permissions");
    return;
  }
}

try {
  const result = await saveFile(options);
  if (result.cancelled) {
    console.log("Download was cancelled");
  } else {
    console.log(`File saved successfully: ${result.uri}`);
    // Example of opening the file immediately after saving
    await openFile({ uri: result.uri, type: options.type });
  }
} catch (error) {
  console.error("Error saving or opening file:", error);
}

Demo Videos

Android

Text file download

https://github.com/user-attachments/assets/cdf7bc14-a5a4-428e-bd4b-5a717a4e5f42

Image file download

https://github.com/user-attachments/assets/e0fd6d5f-3981-430e-872c-573b951595e4

iOS

Text file download

https://github.com/user-attachments/assets/1f8740e8-b740-47e4-909f-cac6e1b188d6

Image file download

https://github.com/user-attachments/assets/564f5285-9a7e-4b70-98cb-41f04905c8cf

API Specification

Functions

saveFile(options: SaveFileOptions): Promise<SaveFileResponse>

  • Description: Saves the Base64 encoded file data using the provided options.

  • Parameters (SaveFileOptions object):

    • name: The name under which the file will be saved.
    • type: The MIME type of the file.
    • data: The file data to be saved.
    • encoding: (Optional) The encoding of the data, either "base64" or "utf8". Defaults to "utf8".
  • Returns (SaveFileResponse object):

    • uri: The URI of the saved file (upon success).
    • cancelled: true if the operation was cancelled by the user (iOS only).

openFile(options: OpenFileOptions): Promise<void>

  • Description: Opens the downloaded file using the native file viewer on the device.

  • Parameters (OpenFileOptions object):

    • uri: The URI of the file to be opened. (Use the uri field of the SaveFileResponse object returned by saveFile.)
    • type: The MIME type of the file.

Permission-related Functions

  • requestPermissionsAsync:
    Requests the WRITE_EXTERNAL_STORAGE permission for Android versions 9 and below. (This permission is not required on Android 10+ and iOS.)

  • getPermissionsAsync:
    Retrieves the current status of the storage write permission.

Exceptions

Common Exceptions

  • ERR_INVALID_ARGUMENT (iOS / Android)

    • Thrown if the name is empty, if the type format is invalid, or if the data is improperly formatted.
  • ERR_FILE_OPEN

    • Thrown when an error occurs while attempting to open a file. This exception is raised if the specified file does not exist or if a compatible application cannot be found to open it.

iOS Specific Exceptions

  • ERR_DOWNLOAD_IN_PROGRESS

    • Thrown if a download is already in progress, preventing simultaneous operations.
  • ERR_MISSING_VIEW_CONTROLLER

    • Thrown if the current view controller cannot be obtained, which prevents the file-saving dialog from being displayed.

Android Specific Exceptions

  • ERR_CONTENT_URI_CREATION (Android 10 and above)

    • Thrown if creating the content URI using the MediaStore API fails.
  • ERR_OUTPUT_STREAM_CREATION (Android 10 and above)

    • Thrown if an OutputStream for writing to the file cannot be created.
  • ERR_DIRECTORY_CREATION (Android 9 and below)

    • Thrown if the Downloads folder does not exist or if attempting to create it fails.
  • ERR_OUT_OF_MEMORY

    • Thrown when the file is too large and an OutOfMemoryError occurs during saving due to insufficient memory.

Platform-specific Behavior

iOS

  • Implementation:
    Uses UIDocumentPickerViewController to allow the user to select a save location.

Android

Android 10 and above (Q+)

  • Implementation:
    Uses the MediaStore API to save files to the system-managed Downloads folder.
  • Permissions:
    No special storage permissions are required on API level 29 and above.

Android 9 and below

  • Implementation:
    Writes directly to the device's Downloads folder using legacy methods.
  • Permissions:
    The WRITE_EXTERNAL_STORAGE permission is required. Use requestPermissionsAsync and getPermissionsAsync to handle permissions.

Web

  • Implementation:
    Utilizes HTML's Blob and <a> tag to download the file.