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-background-streamer

v1.0.0

Published

A powerful background file uploader for Expo/React Native applications

Readme

expo-background-streamer 🚀

A powerful background file uploader and downloader for Expo/React Native applications with encryption support, progress tracking, and robust error handling.

npm version License: MIT

⚠️ Note: This package is actively maintained and tested with the latest Expo SDK.

✨ Features

  • 📱 Background transfers - Upload and download files in the background on iOS and Android
  • 🔒 Encryption support - Optional AES encryption for secure file transfers
  • 🗜️ Compression - Built-in compression to reduce transfer times
  • 📊 Real-time progress - Detailed progress tracking with speed and ETA
  • 🎯 Promise-based API - Simple, modern JavaScript API
  • 🔄 Automatic retry - Built-in retry logic for failed transfers
  • 📝 TypeScript support - Full TypeScript definitions included
  • 🎨 Customizable notifications - Native progress notifications
  • 🚀 Streaming transfers - No temporary files needed
  • 📱 Cross-platform - Works on both iOS and Android

📦 Installation

npx expo install expo-background-streamer

🚀 Quick Start

Basic Upload

import ExpoBackgroundStreamer from "expo-background-streamer";

const uploadId = await ExpoBackgroundStreamer.startUpload({
  url: "https://your-upload-endpoint.com/upload",
  path: "/path/to/your/file.mp4",
  headers: {
    "Content-Type": "application/octet-stream",
    Authorization: "Bearer your-token",
  },
});

console.log(`Upload started with ID: ${uploadId}`);

Basic Download

const downloadId = await ExpoBackgroundStreamer.startDownload({
  url: "https://example.com/large-file.zip",
  path: "/path/to/save/file.zip",
});

console.log(`Download started with ID: ${downloadId}`);

With Progress Tracking

// Listen for upload progress
const uploadSub = ExpoBackgroundStreamer.addListener(
  "upload-progress",
  (event) => {
    console.log(`Upload: ${event.progress}% - ${event.speed} bytes/s`);
    console.log(`ETA: ${event.estimatedTimeRemaining}s`);
  }
);

// Listen for download progress
const downloadSub = ExpoBackgroundStreamer.addListener(
  "download-progress",
  (event) => {
    console.log(`Download: ${event.progress}% - ${event.speed} bytes/s`);
  }
);

// Clean up listeners
uploadSub.remove();
downloadSub.remove();

🔐 Encryption Example

import * as Crypto from "expo-crypto";
import { Buffer } from "buffer";

// Generate encryption keys
const key = await Crypto.getRandomBytesAsync(32);
const nonce = await Crypto.getRandomBytesAsync(16);

const uploadId = await ExpoBackgroundStreamer.startUpload({
  url: "https://your-secure-endpoint.com/upload",
  path: "/path/to/sensitive-file.pdf",
  encryption: {
    enabled: true,
    key: Buffer.from(key).toString("hex"),
    nonce: Buffer.from(nonce).toString("hex"),
  },
});

📚 API Reference

Methods

startUpload(options: UploadOptions): Promise<string>

Starts a background upload and returns the upload ID.

interface UploadOptions {
  url: string; // Upload endpoint URL
  path: string; // Local file path
  method?: string; // HTTP method (default: "POST")
  headers?: Record<string, string>; // HTTP headers
  customTransferId?: string; // Custom transfer ID
  appGroup?: string; // iOS app group identifier
  encryption?: EncryptionOptions; // Encryption settings
  compression?: CompressionOptions; // Compression settings
}

startDownload(options: DownloadOptions): Promise<string>

Starts a background download and returns the download ID.

interface DownloadOptions {
  url: string; // Download URL
  path: string; // Local save path
  headers?: Record<string, string>; // HTTP headers
  customTransferId?: string; // Custom transfer ID
  appGroup?: string; // iOS app group identifier
  encryption?: EncryptionOptions; // Encryption settings
  compression?: CompressionOptions; // Compression settings
}

cancelUpload(uploadId: string): Promise<void>

Cancels an ongoing upload.

cancelDownload(downloadId: string): Promise<void>

Cancels an ongoing download.

getAllActiveTransfers(): Promise<{uploads: Record<string, string>, downloads: Record<string, string>}>

Gets all currently active transfers.

getFileInfo(path: string): Promise<FileInfo>

Gets detailed information about a file.

interface FileInfo {
  exists: boolean;
  size: number;
  name: string;
  extension: string;
  mimeType: string;
}

Encryption Options

interface EncryptionOptions {
  enabled: boolean; // Enable/disable encryption
  key: string; // Hex-encoded encryption key (32 bytes)
  nonce: string; // Hex-encoded nonce (16 bytes)
}

Compression Options

interface CompressionOptions {
  enabled: boolean; // Enable/disable compression
}

Events

Subscribe to transfer events using addListener():

Upload Events

  • upload-progress - Progress updates during upload

    {
      uploadId: string;
      progress: number; // 0-100
      bytesWritten: number;
      totalBytes: number;
      speed: number; // bytes per second
      estimatedTimeRemaining: number; // seconds
    }
  • upload-complete - Upload completed successfully

    {
      uploadId: string;
      response: string;
      responseHeaders: Record<string, string>;
      responseCode: number;
      totalBytes: number;
      duration: number; // seconds
    }
  • upload-cancelled - Upload was cancelled

    {
      uploadId: string;
      bytesWritten: number;
      totalBytes: number;
      reason?: string;
    }

Download Events

  • download-progress - Progress updates during download
  • download-complete - Download completed successfully
  • download-cancelled - Download was cancelled

Error & Debug Events

  • error - Error occurred during transfer
  • debug - Debug information (info, warn, error, debug levels)

🏗️ Platform-Specific Notes

iOS

  • Requires background fetch capability in your app.json:
    {
      "expo": {
        "ios": {
          "backgroundModes": ["background-fetch", "background-processing"]
        }
      }
    }
  • Supports background transfers even when app is terminated
  • Progress notifications shown in notification center
  • Supports iOS app groups for shared container access

Android

  • Requires foreground service permission in your app.json:
    {
      "expo": {
        "android": {
          "permissions": ["FOREGROUND_SERVICE", "WAKE_LOCK"]
        }
      }
    }
  • Supports background transfers with Doze mode optimization
  • Progress notifications shown in notification center
  • Works with Android's background execution limits

🧪 Test Server

An example Express.js backend that accepts upload and download requests via streaming is available in /test_server/. This server can be used for testing the package functionality during development.

🔧 Development Setup

  1. Clone the repository
  2. Install dependencies: npm install
  3. Build the module: npm run build
  4. Run the example app: cd example && npm install && npx expo start

🤝 Contributing

I welcome contributions! Please see my Contributing Guide for details.

Development Workflow

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Update documentation
  6. Submit a pull request

📄 License

MIT License - see the LICENSE file for details.

🙏 Acknowledgments

📞 Support