Are you an LLM? You can read better optimized documentation at /features/barcode-scanning.md for this page in Markdown format
ISBN Barcode Scanning
Quickly add books to your library by scanning their barcode.
Overview
Users can scan the ISBN barcode on physical books using their phone's camera to instantly look up and add books to their library - no typing required.
Requirements
- Camera permission handling (request, denied state, settings redirect)
- Real-time barcode detection from camera feed
- ISBN-10 and ISBN-13 barcode support (EAN-13 format)
- Haptic/audio feedback on successful scan
- Quick add flow after scan
User Flow
┌─────────────────┐
│ Tap Scan Icon │
└────────┬────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐
│ Camera Active │────▶│ Permission │
│ (has permission)│ │ Denied Screen │
└────────┬────────┘ └─────────────────┘
│ Barcode detected
▼
┌─────────────────┐
│ Lookup ISBN │
└────────┬────────┘
│
┌────┴────┐
▼ ▼
┌───────┐ ┌─────────────────┐
│ Found │ │ Not Found │
└───┬───┘ │ (manual entry?) │
│ └─────────────────┘
▼
┌─────────────────┐
│ Book Preview │
│ + Status Select │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Added to Library│
│ (with feedback) │
└─────────────────┘Technical Approach
Expo Camera + Barcode Scanner
Use expo-camera with barcode scanning capabilities:
typescript
import { CameraView, useCameraPermissions } from 'expo-camera';
function BarcodeScanner() {
const [permission, requestPermission] = useCameraPermissions();
const handleBarcodeScanned = ({ type, data }) => {
if (type === 'ean13' || type === 'ean8') {
// data contains the ISBN
lookupBook(data);
}
};
return (
<CameraView
facing="back"
barcodeScannerSettings={{
barcodeTypes: ['ean13', 'ean8'],
}}
onBarcodeScanned={handleBarcodeScanned}
/>
);
}ISBN Validation
Validate scanned barcodes before API lookup:
typescript
function isValidISBN13(isbn: string): boolean {
if (isbn.length !== 13) return false;
if (!isbn.startsWith('978') && !isbn.startsWith('979')) return false;
// Check digit validation
let sum = 0;
for (let i = 0; i < 12; i++) {
sum += parseInt(isbn[i]) * (i % 2 === 0 ? 1 : 3);
}
const checkDigit = (10 - (sum % 10)) % 10;
return checkDigit === parseInt(isbn[12]);
}Debouncing & State
Prevent duplicate scans and handle rapid-fire detection:
typescript
const [scanned, setScanned] = useState(false);
const [lastScannedISBN, setLastScannedISBN] = useState<string | null>(null);
const handleBarcodeScanned = ({ data }) => {
if (scanned || data === lastScannedISBN) return;
setScanned(true);
setLastScannedISBN(data);
// Haptic feedback
Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success);
// Lookup and show result
lookupAndShowBook(data);
};UI Components
Scanner Screen
- Full-screen camera view
- Viewfinder overlay (rectangular guide)
- Cancel/close button
- Flash toggle (for low light)
- Manual ISBN entry fallback link
Book Found Modal
- Book cover thumbnail
- Title and author
- Quick status selector (Want to Read, Currently Reading, Finished)
- "Add to Library" CTA
- "Scan Another" option
Not Found State
- "Book not found" message
- ISBN that was scanned
- Option to try again
- Link to manual search/entry
Edge Cases
| Scenario | Handling |
|---|---|
| Camera permission denied | Show explanation + "Open Settings" button |
| Book not in database | Offer manual entry or search |
| Poor lighting | Suggest enabling flash |
| Non-book barcode scanned | Ignore (only process ISBN prefixes) |
| Network error during lookup | Show retry option with scanned ISBN |
| Multiple barcodes in frame | Process first valid ISBN detected |
Accessibility
- VoiceOver announcements for scan results
- Alternative manual entry always available
- High contrast viewfinder overlay
- Audio feedback option (not just haptic)
Dependencies
json
{
"expo-camera": "~16.0.0",
"expo-haptics": "~14.0.0"
}API Integration
Scanner triggers existing book lookup endpoint:
GET /books/isbn/{isbn}Returns book data if found, 404 if not. See Book Data Sources for lookup strategy.
Metrics
Track to measure feature success:
- Scans attempted per user
- Scan success rate (found vs not found)
- Time from scan to add
- Scanner abandonment rate
- Manual entry fallback usage
Open Questions
- [ ] Support scanning from photos (gallery import)?
- [ ] Batch scanning mode (scan multiple books quickly)?
- [ ] Offline scanning with sync later?
- [ ] What if user scans a book they already have?