A Flutter plugin for handling RAR archives on Android, iOS, macOS, and Web.
This plugin allows you to extract RAR files, list their contents, and supports password-protected archives.
- Extract RAR files (v4 and v5 formats)
- List contents of RAR files
- Support for password-protected RAR archives
- Cross-platform support:
- Android: Uses libarchive via native FFI (Supports RAR5)
- iOS/macOS: Uses UnrarKit (Objective-C)
- Web: Uses WASM-based archive library via JS interop
| Platform | Extract | List | Password |
|---|---|---|---|
| Android | ✅ | ✅ | ✅ |
| iOS | ✅ | ✅ | ✅ |
| macOS | ✅ | ✅ | ✅ |
| Web | ✅ | ✅ | ✅ |
Add this to your package's pubspec.yaml file:
dependencies:
rar: ^latestThe plugin automatically compiles the native RAR library (libarchive) using
CMake during the build process. This ensures the correct binary is bundled for
every architecture (ARM, x86, etc.).
Requirements: To build the app, the developer must have the following installed in their Android SDK:
- Android NDK (Side by side)
- CMake
How to install:
- Open Android Studio.
- Go to Settings/Preferences > Languages & Frameworks > Android SDK.
- Select the SDK Tools tab.
- Check NDK (Side by side) and CMake.
- Click Apply to install.
No other manual configuration is needed.
To allow picking RAR files on iOS, add the following to your
ios/Runner/Info.plist:
<key>UTExportedTypeDeclarations</key>
<array>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>public.data</string>
<string>public.archive</string>
</array>
<key>UTTypeDescription</key>
<string>RAR Archive</string>
<key>UTTypeIdentifier</key>
<string>com.rarlab.rar-archive</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>rar</string>
<string>rev</string>
<string>cbr</string>
</array>
</dict>
</dict>
</array>The plugin bundles the libarchive.js WASM runtime and worker scripts. No
manual script tags are required in your index.html. The plugin automatically
injects the necessary scripts at runtime.
The bundled assets include:
rar_web.js: The plugin's JavaScript interfacelibarchive.js: The WASM loaderlibarchive.wasm: The compiled libarchive libraryworker-bundle.js: The web worker for background processing
import 'package:rar/rar.dart';
Future<void> extractRarFile() async {
final result = await Rar.extractRarFile(
rarFilePath: '/path/to/archive.rar',
destinationPath: '/path/to/destination/folder',
password: 'optional_password', // Optional
);
if (result['success']) {
print('Extraction successful: ${result['message']}');
} else {
print('Extraction failed: ${result['message']}');
}
}import 'package:rar/rar.dart';
Future<void> listRarContents() async {
final result = await Rar.listRarContents(
rarFilePath: '/path/to/archive.rar',
password: 'optional_password', // Optional
);
if (result['success']) {
print('RAR Version: ${result['rarVersion']}'); // e.g., "RAR4" or "RAR5"
print('Files in archive:');
for (final file in result['files']) {
print('- $file');
}
} else {
print('Failed to list contents: ${result['message']}');
}
}On the web platform, file system access is limited. The plugin uses a virtual file system approach:
- When selecting files via a file picker, use
withData: trueto get file bytes - Store the file data using
RarWeb.storeFileData(path, bytes) - Extracted files are stored in the virtual file system and can be accessed via
RarWeb.getFileData(path)
import 'package:rar/rar.dart';
// On web, store file bytes before extraction
if (kIsWeb) {
RarWeb.storeFileData('archive.rar', fileBytes);
}
final result = await Rar.extractRarFile(
rarFilePath: 'archive.rar',
destinationPath: '/extracted',
);
// On web, get extracted file bytes
if (kIsWeb && result['success']) {
final extractedData = RarWeb.getFileData('/extracted/file.txt');
}static Future<Map<String, dynamic>> extractRarFile({
required String rarFilePath,
required String destinationPath,
String? password,
})Extracts a RAR file to a destination directory.
Parameters:
rarFilePath: Path to the RAR filedestinationPath: Directory where files will be extractedpassword: Optional password for encrypted archives
Returns: A map containing:
success(bool): Whether the extraction was successfulmessage(String): Status message or error description
static Future<Map<String, dynamic>> listRarContents({
required String rarFilePath,
String? password,
})Lists all files in a RAR archive.
Parameters:
rarFilePath: Path to the RAR filepassword: Optional password for encrypted archives
Returns: A map containing:
success(bool): Whether the listing was successfulmessage(String): Status message or error descriptionfiles(List): List of file names in the archiverarVersion(String?): Detected RAR version ("RAR4", "RAR5", or "Unknown")
Creating RAR archives is not supported in this plugin because:
- RAR is a proprietary format, and creating RAR archives requires proprietary tools
- The RAR compression algorithm is licensed and cannot be freely used for compression
- Only decompression is allowed under the UnRAR license
For creating archives, consider using the ZIP format instead, which has better native support across all platforms.
The plugin returns descriptive error messages for common issues:
- File not found: The specified RAR file doesn't exist
- Bad password: Incorrect password or password required for encrypted archive
- Bad archive: Corrupt or invalid RAR file
- Unknown format: File is not a valid RAR archive
- Bad data: CRC check failed (data corruption)
This plugin is released under the MIT License.
This plugin uses the following libraries:
| Platform | Library | License |
|---|---|---|
| Android | libarchive | BSD |
| iOS | UnrarKit | BSD |
| macOS | UnrarKit | BSD |
| Web | libarchive.js | MIT |
This plugin uses native code for RAR extraction. The build system automatically compiles the native libraries when you build your Flutter app.
Android now uses libarchive compiled via CMake and accessed via Dart FFI.
- Build System: CMake (configured in
android/build.gradle) - Native Code:
src/rar_native.c - Dependencies:
libarchiveis fetched and built automatically during the Gradle build.
The FFI bindings in lib/src/rar_ffi.dart are hand-written for better control.
If you need to regenerate bindings from the C header, you can use ffigen:
dart run ffigen- Android: Uses
libarchivevia FFI (same as Desktop) - iOS/macOS: Uses UnrarKit library (Objective-C/Swift) via MethodChannel
The web platform uses JavaScript interop with a WASM-based archive library. The WASM library and worker scripts are bundled with the plugin and loaded dynamically at runtime. No external CDN is used, ensuring the plugin works offline.
This plugin follows the federated plugin architecture:
lib/
rar.dart # Main entry point
rar_platform_interface.dart # Abstract platform interface
src/
rar_method_channel.dart # Mobile implementation (iOS/macOS)
rar_ffi.dart # FFI implementation (Android)
rar_web.dart # Web implementation
The plugin includes comprehensive tests for all platforms.
Use the test runner script:
# Run unit tests only
./test_runner.sh unit
# Run tests for a specific platform
./test_runner.sh macos
./test_runner.sh web
# Run all desktop tests
./test_runner.sh desktop
# Run all mobile tests
./test_runner.sh mobile
# Run all tests
./test_runner.sh alltest/
rar_platform_interface_test.dart # Platform interface unit tests
rar_test.dart # Main Rar class unit tests
example/
integration_test/
rar_integration_test.dart # Integration tests for all platforms
The example app (example/lib/main.dart) demonstrates all plugin features across platforms. It uses a reusable FileBrowser widget (example/lib/file_browser.dart) which provides:
- File picker for selecting RAR archives
- Password support for encrypted archives
- File browser with tree view for archive contents
- Content viewer supporting:
- Images (PNG, JPG, GIF, etc.)
- Text files (TXT, JSON, XML, etc.)
- Binary files (hex dump view)
Run the example:
cd example
flutter run -d macos # or chrome, etc.Contributions are welcome! Please feel free to submit a Pull Request.
- Lokesh jangid lkrjangid1
- Chris Sells csells
If you find a bug or want to request a new feature, please open an issue on GitHub.