react-native-zip-archive
Version:
A TurboModule wrapper on ZipArchive for React Native's New Architecture
226 lines (159 loc) • 7.37 kB
Markdown
# React Native Zip Archive [](https://www.npmjs.com/package/react-native-zip-archive) [-61dafb)](https://reactnative.dev/docs/new-architecture-intro)
Zip archive utility for React Native.
> **v8.0** requires React Native ≥ 0.70 with New Architecture enabled. For older RN versions, use v7.x:
> ```bash
> npm install react-native-zip-archive@^7.0.0
> ```
> **iOS:** Version 7.0.0+ requires a deployment target of iOS 15.5+ to comply with App Store privacy policy.
## Requirements
| Platform | Minimum Version |
|----------|-----------------|
| React Native | >= 0.70.0 |
| React | >= 18.0.0 |
| iOS | >= 15.5 |
| Android | >= API 23 (Android 6.0) |
## Installation
```bash
npm install react-native-zip-archive
```
**iOS:**
```bash
cd ios && pod install
```
> To enable New Architecture, see [MIGRATION.md](./MIGRATION.md).
## Usage
```js
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](https://github.com/johanneslumpe/react-native-fs) to access the file system:
```js
import { DocumentDirectoryPath } from 'react-native-fs'
```
## API
### `zip(source: string | string[], target: string, compressionLevel?: number): Promise<string>`
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)`.
- `compressionLevel` is 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)
```js
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)`.
- `compressionLevel` is 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 `STANDARD` works.
```js
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(source: string, target: string, charset?: string): Promise<string>`
Unzip from source to target.
> The `charset` parameter is only supported on Android (default: `UTF-8`). On iOS it is ignored.
```js
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))
```
### `unzipWithPassword(source: string, target: string, password: string): Promise<string>`
Unzip a password-protected archive.
```js
unzipWithPassword(sourcePath, targetPath, 'password')
.then((path) => console.log(`unzip completed at ${path}`))
.catch((error) => console.error(error))
```
### `unzipAssets(assetPath: string, target: string): Promise<string>`
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.
```js
unzipAssets('./myFile.zip', DocumentDirectoryPath)
.then((path) => console.log(`unzip completed at ${path}`))
.catch((error) => console.error(error))
```
### `getUncompressedSize(source: string, charset?: string): Promise<number>`
Returns the total uncompressed size of all files in the zip archive (in bytes).
> The `charset` parameter is only supported on Android. On iOS it is ignored.
```js
getUncompressedSize(sourcePath)
.then((size) => console.log(`Uncompressed size: ${size} bytes`))
.catch((error) => console.error(error))
```
### `subscribe(callback: ({ progress: number, filePath: string }) => void): EmitterSubscription`
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 `filePath` in your callback to ensure it matches the operation you care about. Remember to call `.remove()` on the returned subscription when done.
```js
import { useEffect } from 'react'
useEffect(() => {
const sub = subscribe(({ progress, filePath }) => {
console.log(`progress: ${progress}, file: ${filePath}`)
})
return () => sub.remove()
}, [])
```
## Platform Support
| 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 |
### Cross-Platform Notes
- **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 and `content://` URIs on Android. Not supported on iOS.
## Expo
This library **requires an Expo Development Build** and does not work in Expo Go because it includes custom native code. See the [playground app](./playground/) for a working Expo Development Build example.
## Playground
A fully-featured [playground app](./playground/) is included to demonstrate every API method.
## Migrating from v7
See [MIGRATION.md](./MIGRATION.md) for detailed migration instructions.
## Testing
```bash
npm test
```
## Contributing
See the [playground app](./playground/) for testing and contribution reference.
## Related Projects
- [ZipArchive](https://github.com/ZipArchive/ZipArchive)
- [zip4j](https://github.com/srikanth-lingala/zip4j)
---
[](https://www.buymeacoffee.com/plrthink)