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

@athex/react-native-bg-upload

v1.0.1

Published

Background uploader for react native applications

Readme

✨ Features

  • 🔄 Resumable: Survives app kills, low memory, and device reboots
  • 📦 Chunking: Automatic chunking for large files with resume capability
  • 🔁 Retry Logic: Exponential backoff with jitter for transient failures
  • 📡 Network Aware: Auto pause/resume on connectivity changes
  • 🔐 Secure: Credential refresh hooks, no long-term token storage
  • 📱 Native Notifications: Foreground service with progress (Android)
  • 💾 Persistent Queue: MMKV-based storage for instant recovery
  • 🎣 React Hooks: useUpload() for seamless integration
  • 📊 Observable: Progress, completion, error events
  • 🧪 Battle Tested: Comprehensive test suite included

📱 Platform Support

| Feature | Android (API 21+) | iOS (11+) | | :--- | :---: | :---: | | Background Uploads | ✅ WorkManager | ✅ URLSession | | App Kill Survival | ✅ | ✅ | | Device Reboot | ✅ | ✅ | | Chunking & Resume | ✅ | ✅ | | Retry & Backoff | ✅ | ✅ | | Progress Notification | ✅ | N/A | | Network Monitoring | ✅ | ✅ |

📦 Installation

npm install react-native-bg-upload react-native-mmkv @react-native-community/netinfo
# or
yarn add react-native-bg-upload react-native-mmkv @react-native-community/netinfo

iOS: cd ios && pod install

🚀 Quick Start

import { BgUpload } from 'react-native-bg-upload';

// Start an upload
const taskId = await BgUpload.start({
  id: 'video-upload-1',
  url: 'https://api.example.com/upload',
  path: 'file:///path/to/large-video.mp4',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  chunking: {
    enabled: true, // Auto-enabled for files > 5MB
    chunkSize: 5 * 1024 * 1024 // 5MB chunks
  },
  retryPolicy: {
    maxAttempts: 5,
    baseDelay: 1000,
    maxDelay: 30000
  },
  // Android only
  notification: {
    enabled: true,
    title: 'Uploading Video'
  }
});

🎣 Using Hooks

import { useUpload } from 'react-native-bg-upload';

function UploadScreen({ taskId }) {
  const task = useUpload(taskId);

  if (!task) return null;

  return (
    <View>
      <Text>State: {task.state}</Text>
      <Text>Progress: {task.progress}%</Text>
      <ProgressBar progress={task.progress / 100} />
      
      {task.state === 'UPLOADING' && (
        <Button title="Pause" onPress={() => BgUpload.pause(taskId)} />
      )}
      
      {task.error && <Text style={{color: 'red'}}>{task.error}</Text>}
    </View>
  );
}

📖 API Reference

BgUpload.start(options): Promise<string>

Start a background upload. Returns the task ID.

Options

| Option | Type | Required | Description | | :--- | :--- | :---: | :--- | | id | string | ✅ | Unique task identifier | | url | string | ✅ | Upload destination URL | | path | string | ✅ | Absolute file path (file://) | | method | string | | HTTP method (default: POST) | | headers | object | | HTTP headers | | networkType | string | | 'ANY', 'WIFI_ONLY', 'UNMETERED' | | chunking | object | | Chunking configuration | | retryPolicy | object | | Retry configuration | | onCredentialRefresh | function | | Token refresh callback | | notification | object | | Android notification config |

Chunking Options

{
  enabled?: boolean;       // Enable chunking (default: true for > 5MB)
  chunkSize?: number;      // Chunk size in bytes (default: 5MB)
  maxConcurrent?: number;  // Max concurrent chunks (default: 3)
}

Retry Policy

{
  maxAttempts?: number;   // Max retry attempts (default: 5)
  baseDelay?: number;     // Base delay in ms (default: 1000)
  maxDelay?: number;      // Max delay in ms (default: 30000)
  jitter?: number;        // Random jitter in ms (default: 500)
}

Other Methods

  • BgUpload.cancel(taskId): Cancel upload
  • BgUpload.pause(taskId): Pause upload
  • BgUpload.resume(taskId): Resume upload
  • BgUpload.getPending(): Get all pending uploads
  • BgUpload.addListener(event, callback): Add event listener

🔐 Security

Credential Refresh

BgUpload.start({
  id: 'secure-upload',
  url: 'https://api.example.com/upload',
  path: filePath,
  onCredentialRefresh: async () => {
    // Refresh your auth token
    const newToken = await refreshAuthToken();
    return {
      'Authorization': `Bearer ${newToken}`
    };
  }
});

Best Practices

  • ✅ Use short-lived signed URLs (S3, Azure)
  • ✅ Implement onCredentialRefresh for token rotation
  • ✅ Don't store tokens in upload options (use refresh hook)
  • ✅ Use HTTPS only
  • ❌ Don't hardcode credentials

🧪 Testing

Running Tests

yarn test                    # Unit tests
yarn test:integration       # Integration tests (requires mock server)

Example Test Scenarios

  • Large file (1GB+) with chunking
  • App kill during upload → resume
  • Network offline/online toggle
  • Retry on server 500 errors
  • Notification cancel action (Android)

See IMPLEMENTATION_NOTES.md for server-side contract.

📝 Implementation Notes

Android

  • Uses WorkManager for reliable background execution
  • Foreground Service with notification during active uploads
  • Persists task state to survive process death
  • Chunks stored with offset tracking for resume

iOS

  • Uses URL Session background configuration
  • OS handles upload continuation when app is killed
  • Delegate callbacks for progress/completion
  • Task state synced via UserDefaults

Storage

  • Queue: MMKV for instant read/write
  • Tasks: Serialized JSON with chunk metadata
  • Credentials: Never persisted (use refresh hook)

🤝 Contributing

See CONTRIBUTING.md

📄 License

MIT © 2025

🔗 Links