Stats
Actions
Tags
From ncode-saas-toolkit-mobile
Camera access and photo library with Expo. Covers taking photos, picking from gallery, image manipulation, and permissions. Use when building features that involve photos, camera, or image uploads.
How this skill is triggered — by the user, by Claude, or both
Slash command
/ncode-saas-toolkit-mobile:react-native-cameraThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
```bash
npx expo install expo-camera expo-image-picker expo-media-library expo-file-system
Add to app.json or app.config.ts:
{
"expo": {
"plugins": [
[
"expo-camera",
{ "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera." }
],
[
"expo-image-picker",
{ "photosPermission": "Allow $(PRODUCT_NAME) to access your photos." }
]
]
}
}
The most common pattern:
import * as ImagePicker from 'expo-image-picker';
async function pickImage() {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!result.canceled) {
const imageUri = result.assets[0].uri;
// Use imageUri for display or upload
return imageUri;
}
}
import * as ImagePicker from 'expo-image-picker';
async function takePhoto() {
// Request camera permission
const { status } = await ImagePicker.requestCameraPermissionsAsync();
if (status !== 'granted') {
Alert.alert('Permission needed', 'Camera access is required to take photos.');
return;
}
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
aspect: [1, 1],
quality: 0.8,
});
if (!result.canceled) {
return result.assets[0].uri;
}
}
import storage from '@react-native-firebase/storage';
async function uploadImage(uri: string, userId: string): Promise<string> {
const filename = `${userId}/${Date.now()}.jpg`;
const ref = storage().ref(`images/${filename}`);
await ref.putFile(uri);
const downloadUrl = await ref.getDownloadURL();
return downloadUrl;
}
async function addPhoto() {
// 1. Pick image
const uri = await pickImage();
if (!uri) return;
// 2. Show loading state
setUploading(true);
// 3. Upload to Firebase Storage
const downloadUrl = await uploadImage(uri, auth().currentUser.uid);
// 4. Save reference to Firestore
await firestore().collection('photos').add({
userId: auth().currentUser.uid,
imageUrl: downloadUrl,
createdAt: firestore.FieldValue.serverTimestamp(),
});
setUploading(false);
}
import { Image } from 'react-native';
// From local URI (before upload)
<Image source={{ uri: localUri }} style={{ width: 200, height: 200 }} />
// From Firebase Storage URL (after upload)
<Image source={{ uri: downloadUrl }} style={{ width: 200, height: 200 }} />
quality: 0.8 or lower. Full-quality photos are huge.ref.putFile(uri).on('state_changed', ...) for upload progress.expo-image (fast cached image component) instead of Image for lists.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub dangogit/ncode-saas-toolkit-mobile --plugin ncode-saas-toolkit-mobile