Lightweight Expo file download utility with caching, cancellation, and headers support.
- 🎣 Hook API –
useDownload()with built-in state - ❌ Cancellation – stop downloads mid-flight
- 🔐 Custom Headers – auth tokens, signed URLs
- 💾 Smart Caching – skip re-downloading files
npx expo install expodownload expo-file-system expo-media-libraryexpo-file-system and expo-media-library are peer dependencies — installing them with npx expo install ensures the versions match your Expo SDK.
import { useDownload } from 'expodownload';
export default function App() {
const { download, isDownloading, progress, cancel } = useDownload();
return (
<View>
<Button
title={isDownloading ? `${Math.round(progress * 100)}%` : 'Download'}
onPress={() => download('https://example.com/image.jpg')}
disabled={isDownloading}
/>
{isDownloading && <Button title="Cancel" onPress={cancel} />}
</View>
);
}That's it! 🎉
- 📖 API Reference - Complete API documentation
- 💡 Examples - Advanced usage examples
const { download } = useDownload({
headers: { Authorization: 'Bearer your-token' },
});
await download('https://api.example.com/protected/file.pdf');const { download } = useDownload({
cache: true, // Reuse the file if it already exists
});
await download('https://example.com/avatar.jpg');const { download } = useDownload({
saveToGallery: true, // Off by default
albumName: 'My Photos',
});
await download('https://example.com/photo.jpg');import { downloadFile } from 'expodownload';
const result = await downloadFile({
url: 'https://example.com/file.pdf',
fileName: 'my-file.pdf',
onProgress: (progress) => console.log(progress),
});- Expo SDK 54+ (
expo-file-system19+,expo-media-library17+) - React Native 0.76+
- React 18+
For Expo SDK 53 and below, use expodl@1.x (this package's previous name).
- Package renamed from
expodltoexpodownload. Uninstallexpodland installexpodownload; imports change accordingly. saveToGallerynow defaults tofalse. Downloads land in the app's document directory unless you opt in. PasssaveToGallery: trueto keep the old behavior (media files only).overwriteoption removed.cache: truealone now reuses an existing file; omit it to always re-download.expo-file-systemandexpo-media-libraryare peer dependencies. Install them in your app withnpx expo install.cancel()now actually cancels the underlying download (previously it only paused), and the pendingdownload()promise rejects with codeCANCELLED.DownloadResult.sizeremoved (it was never populated).
MIT © Pavan Kommi