Skip to main content

Extraction

Extract ZIP archives with real-time progress tracking.

Basic Extraction​

import { getUnzip } from 'react-native-nitro-unzip';

const unzip = getUnzip();
const task = unzip.extract('/path/to/archive.zip', '/path/to/output');

const result = await task.await();
console.log(`Extracted ${result.extractedFiles} files`);

The destination directory is created automatically if it doesn't exist.

Progress Tracking​

Register a progress callback to get real-time updates during extraction:

const task = unzip.extract('/path/to/archive.zip', '/path/to/output');

task.onProgress((progress) => {
console.log(`${(progress.progress * 100).toFixed(0)}%`);
console.log(`${progress.extractedFiles}/${progress.totalFiles} files`);
console.log(`Speed: ${progress.speed.toFixed(0)} files/sec`);
console.log(`Processed: ${progress.processedBytes} bytes`);
});

const result = await task.await();

Progress callbacks are throttled to approximately one update per second to avoid unnecessary overhead. The first file and final file always trigger a callback regardless of throttling.

Progress Fields​

FieldTypeDescription
extractedFilesnumberFiles extracted so far
totalFilesnumberTotal files in the archive
progressnumber0.0 to 1.0
speednumberCurrent speed in files per second
processedBytesnumberBytes processed so far

Result​

The await() method resolves with an UnzipResult:

const result = await task.await();

if (result.success) {
console.log(`Extracted ${result.extractedFiles} files`);
console.log(`Duration: ${result.duration}ms`);
console.log(`Average speed: ${result.averageSpeed.toFixed(0)} files/sec`);
console.log(`Total size: ${result.totalBytes} bytes`);
}
FieldTypeDescription
successbooleanWhether extraction completed
extractedFilesnumberTotal files extracted
totalFilesnumberTotal files in the archive
durationnumberDuration in milliseconds
averageSpeednumberAverage files per second
totalBytesnumberSize of the ZIP file in bytes

Concurrent Extractions​

Multiple extractions can run simultaneously. Each task operates independently:

const task1 = unzip.extract('/path/to/first.zip', '/output/first');
const task2 = unzip.extract('/path/to/second.zip', '/output/second');

const [result1, result2] = await Promise.all([
task1.await(),
task2.await(),
]);

File URI Support​

Both file:// URIs and plain absolute paths are accepted:

// Both work
unzip.extract('file:///path/to/archive.zip', '/output');
unzip.extract('/path/to/archive.zip', '/output');

content:// URIs (returned by Android's Storage Access Framework) are not accepted — resolve them to a filesystem path first.

Transactional behaviour (0.5.0+)​

Extraction is all-or-nothing. If anything fails after the first byte is written — a corrupt archive entry, the disk filling up, a write error, or cancellation between entries — the library rolls back every file AND every intermediate directory it created before re-throwing.

try {
await unzip.extract('/path/to/archive.zip', '/output').await();
} catch (err) {
// /output is exactly as it was before the call — empty or as the user
// left it. No half-extracted state to clean up.
}

This applies to both the unencrypted path and the Android password path. The iOS password path (driven by SSZipArchive's batch API) can't be aborted mid-archive, but pre-validation still guarantees no writes happen if any entry would be malicious.