Zip archive utility for React Native.
v8.0 requires React Native ≥ 0.70 with New Architecture enabled. For older RN versions, use v7.x:
npm install react-native-zip-archive@^7.0.0iOS: Version 7.0.0+ requires a deployment target of iOS 15.5+ to comply with App Store privacy policy.
| Platform | Minimum Version |
|---|---|
| React Native | >= 0.70.0 |
| React | >= 18.0.0 |
| iOS | >= 15.5 |
| Android | >= API 23 (Android 6.0) |
npm install react-native-zip-archiveiOS:
cd ios && pod installTo enable New Architecture, see MIGRATION.md.
import {
zip,
zipWithPassword,
unzip,
unzipWithPassword,
unzipAssets,
subscribe,
isPasswordProtected,
getUncompressedSize,
DEFAULT_COMPRESSION,
NO_COMPRESSION,
BEST_SPEED,
BEST_COMPRESSION
} from 'react-native-zip-archive'You may also want to use react-native-fs to access the file system:
import { DocumentDirectoryPath } from 'react-native-fs'Zip a folder (string) or an array of files to the target path.
- To zip a single file, pass it as an array:
zip([file], target). compressionLevelis ignored on iOS when the source is a file array. Use a directory source for custom compression on iOS.
Compression Level Constants:
DEFAULT_COMPRESSION(-1)NO_COMPRESSION(0)BEST_SPEED(1)BEST_COMPRESSION(9)
const sourcePath = DocumentDirectoryPath
const targetPath = `${DocumentDirectoryPath}/myFile.zip`
zip(sourcePath, targetPath)
.then((path) => console.log(`zip completed at ${path}`))
.catch((error) => console.error(error))zipWithPassword(source: string | string[], target: string, password: string, encryptionType?: string, compressionLevel?: number): Promise<string>
Zip with password protection.
- To zip a single file, pass it as an array:
zipWithPassword([file], target, password). compressionLevelis ignored on iOS when the source is a file array.
Encryption Types:
'STANDARD'— Standard ZIP encryption (default)'AES-128'— AES 128-bit'AES-256'— AES 256-bit
iOS: Both AES-128 and AES-256 use AES-256 internally. AES encryption is not supported for file arrays on iOS — only
STANDARDworks.
const sourcePath = DocumentDirectoryPath
const targetPath = `${DocumentDirectoryPath}/myFile.zip`
zipWithPassword(sourcePath, targetPath, 'password', 'STANDARD')
.then((path) => console.log(`zip completed at ${path}`))
.catch((error) => console.error(error))Unzip from source to target.
The
charsetparameter is only supported on Android (default:UTF-8). On iOS it is ignored.
const sourcePath = `${DocumentDirectoryPath}/myFile.zip`
const targetPath = DocumentDirectoryPath
unzip(sourcePath, targetPath, 'UTF-8')
.then((path) => console.log(`unzip completed at ${path}`))
.catch((error) => console.error(error))Unzip a password-protected archive.
unzipWithPassword(sourcePath, targetPath, 'password')
.then((path) => console.log(`unzip completed at ${path}`))
.catch((error) => console.error(error))Unzip a file from the Android assets folder. Android only.
assetPath is the relative path inside the pre-bundled assets folder (e.g. folder/myFile.zip). Do not pass an absolute path.
unzipAssets('./myFile.zip', DocumentDirectoryPath)
.then((path) => console.log(`unzip completed at ${path}`))
.catch((error) => console.error(error))Returns the total uncompressed size of all files in the zip archive (in bytes).
The
charsetparameter is only supported on Android. On iOS it is ignored.
getUncompressedSize(sourcePath)
.then((size) => console.log(`Uncompressed size: ${size} bytes`))
.catch((error) => console.error(error))Subscribe to progress events. Useful for showing a progress bar.
progress— value from 0 to 1 (1 = completed)filePath— the zip file path (empty on iOS for zip operations)
The event is global — check
filePathin your callback to ensure it matches the operation you care about. Remember to call.remove()on the returned subscription when done.
import { useEffect } from 'react'
useEffect(() => {
const sub = subscribe(({ progress, filePath }) => {
console.log(`progress: ${progress}, file: ${filePath}`)
})
return () => sub.remove()
}, [])| Feature | iOS | Android | Notes |
|---|---|---|---|
zip (folder) |
✅ | ✅ | — |
zip (files array) |
✅ | ✅ | Compression level ignored on iOS |
zipWithPassword (folder) |
✅ | ✅ | AES encryption supported |
zipWithPassword (files array) |
✅ | iOS: only STANDARD encryption |
|
unzip |
✅ | ✅ | Charset ignored on iOS |
unzipWithPassword |
✅ | ✅ | — |
unzipAssets |
❌ | ✅ | Android only |
isPasswordProtected |
✅ | ✅ | — |
getUncompressedSize |
✅ | ✅ | Charset ignored on iOS |
| Progress Events | ✅ | ✅ | File path empty on iOS for zip |
- Compression levels: Android supports 0–9 for all operations. iOS supports them only for folder operations.
- Encryption: Android supports AES-128, AES-256, and Standard ZIP encryption for all operations. iOS supports AES and Standard for folders, but only Standard for file arrays.
- Charset: Android supports custom charsets (default UTF-8). iOS always uses UTF-8.
- unzipAssets: Supports
assets/folder andcontent://URIs on Android. Not supported on iOS.
This library requires an Expo Development Build and does not work in Expo Go because it includes custom native code. See playground-expo for a working Expo Development Build example.
Two fully-featured playground apps are included to demonstrate every API method:
- playground-expo — Expo SDK 55 with Expo Router (New Architecture)
- playground-rn — Bare React Native 0.83.9 (New Architecture)
Both apps consume the local library via file:.. and include Maestro E2E tests.
See MIGRATION.md for detailed migration instructions.
npm testSee the playground apps for testing and contribution reference.
