| Crates.io | tauri-plugin-native-camera |
| lib.rs | tauri-plugin-native-camera |
| version | 0.1.0 |
| created_at | 2026-01-16 08:30:13.716745+00 |
| updated_at | 2026-01-16 08:30:13.716745+00 |
| description | A Tauri plugin to capture photos using the device's native camera app |
| homepage | |
| repository | https://github.com/kushaldas/tauri-plugin-native-camera |
| max_upload_size | |
| id | 2048168 |
| size | 218,366 |
A Tauri plugin that captures photos using the device's native camera application.
This plugin uses Android's ACTION_IMAGE_CAPTURE intent to open the system camera app (Samsung Camera, Google Camera, Pixel Camera, etc.) rather than implementing a custom camera UI. This ensures:
| Platform | Supported |
|---|---|
| Android | ✅ |
| iOS | ❌ (planned) |
| Desktop | ❌ |
Add the plugin to your Cargo.toml:
[dependencies]
tauri-plugin-native-camera = "0.1"
Or for Android-only (recommended to avoid compilation issues on other platforms):
[target.'cfg(target_os = "android")'.dependencies]
tauri-plugin-native-camera = "0.1"
Install the JavaScript bindings:
npm install tauri-plugin-native-camera-api
# or
pnpm add tauri-plugin-native-camera-api
# or
yarn add tauri-plugin-native-camera-api
In your src-tauri/src/lib.rs:
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
// Register the plugin (Android-only)
#[cfg(target_os = "android")]
.plugin(tauri_plugin_native_camera::init())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
Create or update src-tauri/capabilities/android.json:
{
"identifier": "android-capability",
"platforms": ["android"],
"windows": ["main"],
"permissions": [
"native-camera:allow-take-picture"
]
}
The plugin's manifest merger should add this automatically, but if needed, add to your src-tauri/gen/android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
import { takePicture } from 'tauri-plugin-native-camera-api';
async function capturePhoto() {
try {
const result = await takePicture();
console.log('Photo captured!');
console.log('Dimensions:', result.width, 'x', result.height);
// Use the base64 image data
const imgElement = document.getElementById('preview') as HTMLImageElement;
imgElement.src = `data:image/jpeg;base64,${result.imageData}`;
} catch (error) {
if (error === 'Camera operation was cancelled by user') {
console.log('User cancelled');
} else {
console.error('Camera error:', error);
}
}
}
use tauri_plugin_native_camera::NativeCameraExt;
#[tauri::command]
async fn take_photo(app: tauri::AppHandle) -> Result<String, String> {
let result = app.native_camera().take_picture()
.map_err(|e| e.to_string())?;
Ok(result.image_data)
}
takePicture()Opens the device's native camera app and captures a photo.
Returns: Promise<CaptureResult>
interface CaptureResult {
/** Base64-encoded JPEG image data */
imageData: string;
/** Width of the captured image in pixels */
width: number;
/** Height of the captured image in pixels */
height: number;
}
Throws: Error with one of the following messages:
"Camera operation was cancelled by user" - User pressed back or cancelled"Camera permission denied" - User denied camera permission"No camera available on this device" - Device has no camera"Failed to read captured photo: ..." - Error processing the imagePermission Check: The plugin first checks if camera permission is granted. If not, it requests permission from the user.
Create Temp File: A temporary file is created in the app's cache directory to store the captured photo.
Launch Camera Intent: The plugin creates an ACTION_IMAGE_CAPTURE intent with the temp file URI and launches the system camera app.
Handle Result: When the user takes a photo and confirms, the plugin:
| Feature | Native Camera (this plugin) | Custom Camera UI |
|---|---|---|
| UI Familiarity | ✅ Users' own camera app | ❌ Learning curve |
| Safe Area Handling | ✅ Handled by system | ⚠️ May have issues |
| Device Compatibility | ✅ Universal | ⚠️ May vary |
| Camera Features | ✅ Full device features | ❌ Limited |
| Code Complexity | ✅ Simple (~200 lines) | ❌ Complex (~1000+ lines) |
| Maintenance | ✅ Minimal | ❌ Ongoing |
Ensure your app has the camera permission in the manifest and that the user has granted it. The plugin automatically requests permission if not granted.
Make sure the FileProvider is correctly configured. Check logcat for errors:
adb logcat | grep -i NativeCameraPlugin
This is usually due to the photo file not being accessible. Ensure the FileProvider paths are correctly configured in the manifest.
Starting with Android 11 (API level 30), apps need to declare which other apps they intend to interact with. This plugin automatically includes the necessary <queries> declaration in its manifest:
<queries>
<intent>
<action android:name="android.media.action.IMAGE_CAPTURE" />
</intent>
</queries>
This allows the plugin to discover and launch camera apps on Android 11+. The manifest merger should include this automatically when you add the plugin dependency.
If you're experiencing issues with the camera not launching on Android 11+ devices, verify that the queries element is present in your merged manifest by checking:
# View merged manifest
cat src-tauri/gen/android/app/build/intermediates/merged_manifest/*/AndroidManifest.xml | grep -A3 "queries"
This plugin uses the host app's existing FileProvider (with authority ${applicationId}.fileprovider) to share the photo file URI with the camera app. Your app must have a FileProvider configured with cache-path access.
The default Tauri Android template includes this configuration. If you have a custom setup, ensure your file_paths.xml includes:
<cache-path name="my_cache_images" path="." />
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License - see LICENSE for details.
Kushal Das mail@kushaldas.in