Motivation
Modern web applications frequently need camera access — for capturing photos, scanning QR codes / barcodes, document scanning, video previews, and more. With the widespread support of the MediaDevices.getUserMedia() API across all modern browsers (including mobile), camera access from the web is now reliable and commonplace.
Vaadin currently has no first-class component for camera access. Developers must drop down to raw JavaScript, call getUserMedia() manually, attach a stream to a <video> element, handle permissions/errors, and — if QR scanning is needed — integrate a separate library like jsQR or zxing-js. This is complex, repetitive, and hard to maintain across projects.
Proposed Component: Camera (working name)
A new component that accesses the device camera, displays a live preview, and optionally scans for QR codes / barcodes in real time.
Core behavior
┌──────────────────────────────────────────────────┐
│ │
│ │
│ [ live camera preview ] │
│ │
│ ┌─────────────┐ │
│ │ ▓▓▓▓▓▓▓ │ ← QR scan overlay │
│ │ ▓ ▓ ▓ ▓ │ (optional) │
│ │ ▓▓▓▓▓▓▓ │ │
│ └─────────────┘ │
│ │
├──────────────────────────────────────────────────┤
│ [ 📸 Capture ] [ 🔄 Flip ] [ QR: ON/OFF ] │
└──────────────────────────────────────────────────┘
- Accesses the device camera(s) via
getUserMedia() and shows a live video preview.
- Supports capturing photos (snapshot to image).
- Optionally enables real-time QR code / barcode scanning with a scan-overlay UI.
- Handles camera selection (front/back), especially important on mobile devices.
Suggested API
Camera camera = new Camera();
// Configure
camera.setFacingMode(CameraFacingMode.ENVIRONMENT); // back camera on mobile
camera.setQrScanningEnabled(true); // turn on QR detection
camera.setPhotoResolution(1920, 1080);
// Capture a photo
camera.capturePhoto();
camera.addPhotoCaptureListener(e -> {
byte[] jpeg = e.getImageData(); // captured photo as JPEG bytes
// save to DB, S3, etc.
});
// QR code scanning
camera.addQrCodeDetectedListener(e -> {
String code = e.getValue(); // decoded QR code text
Notification.show("Scanned: " + code);
});
// Lifecycle
camera.start(); // request camera permission and begin stream
camera.stop(); // release the camera
camera.flip(); // switch between front/back cameras
// Error handling
camera.addErrorListener(e -> {
String msg = e.getMessage(); // permission denied, no camera, etc.
});
Key features
| Feature |
Description |
| Live camera preview |
Real-time video feed from the device camera |
| Photo capture |
Take a snapshot and retrieve it as JPEG/PNG bytes or data URL |
| QR code scanning |
Real-time QR code detection and decoding (e.g. via jsQR / zxing-js) |
| Barcode scanning |
Optionally support 1D barcodes (EAN, UPC, Code128, etc.) |
| Camera selection |
Switch between front/back cameras (facingMode) |
| Scan overlay |
Configurable viewfinder/reticle UI for QR scanning guidance |
| Permission handling |
Graceful handling of permission denied / no camera / insecure context |
| Responsive |
Full-screen on mobile, inline panel on desktop |
| Theme variants |
Lumo theme variants for overlay style and control layout |
| Server-side events |
Photo and QR data delivered to the server via Vaadin's communication layer |
Use cases
- QR code login / check-in — scan a QR to authenticate or register attendance.
- Product / asset scanning — scan QR/barcodes for inventory, logistics, retail.
- Document / ID capture — photograph documents, receipts, or IDs.
- Profile photos — capture user avatars directly from the camera.
- Contactless info — scan QR codes on posters, menus, packaging.
Alternatives considered
- Manual
getUserMedia() + <video> via Element API: every team reimplements permission handling, stream lifecycle, camera switching, and QR detection. High duplication and inconsistent quality.
- Third-party JS libraries:
jsQR, @zxing/library, html5-qrcode — capable but require custom Vaadin wrappers, have no server-side integration, and aren't maintained alongside Vaadin releases.
- Vaadin Directory add-ons: a few camera/signature add-ons exist but are limited in scope and not QR-focused.
A built-in Camera component with optional QR scanning would cover the most common camera needs out of the box, with proper server-side integration and Lumo theming.
Prior art
- HTML5
MediaDevices.getUserMedia() — the underlying web standard, now universally supported
- PrimeFaces —
Camera (photo capture via <p:camera>)
- ** Ionic / Capacitor** — community camera + QR scanner plugins
- NativeScript / Cordova —
cordova-plugin-qrscanner, phone camera plugins
- jsQR / @zxing/library — popular open-source QR decoding libraries
Implementation notes
The component would wrap a <video> element fed by getUserMedia(). For QR scanning, a lightweight decoder (e.g. jsQR or @zxing/browser) would analyze video frames on the client and emit decoded values to the server via Vaadin's RPC. Photo capture would draw the current video frame to a <canvas> and encode it server-side. All browser permission prompts and error states would be surfaced as server-side events.
Accessibility & privacy
- Camera access requires HTTPS (secure context) and explicit user permission — the component should surface permission-denied states clearly.
- The scan overlay and control buttons should be keyboard-accessible with proper ARIA labels.
- The component should always release the camera stream (
stop()) when no longer needed to protect user privacy.
I'd be happy to help refine the API. Is this something the team would consider for Vaadin 26?
Motivation
Modern web applications frequently need camera access — for capturing photos, scanning QR codes / barcodes, document scanning, video previews, and more. With the widespread support of the
MediaDevices.getUserMedia()API across all modern browsers (including mobile), camera access from the web is now reliable and commonplace.Vaadin currently has no first-class component for camera access. Developers must drop down to raw JavaScript, call
getUserMedia()manually, attach a stream to a<video>element, handle permissions/errors, and — if QR scanning is needed — integrate a separate library likejsQRorzxing-js. This is complex, repetitive, and hard to maintain across projects.Proposed Component:
Camera(working name)A new component that accesses the device camera, displays a live preview, and optionally scans for QR codes / barcodes in real time.
Core behavior
getUserMedia()and shows a live video preview.Suggested API
Key features
facingMode)Use cases
Alternatives considered
getUserMedia()+<video>via Element API: every team reimplements permission handling, stream lifecycle, camera switching, and QR detection. High duplication and inconsistent quality.jsQR,@zxing/library,html5-qrcode— capable but require custom Vaadin wrappers, have no server-side integration, and aren't maintained alongside Vaadin releases.A built-in
Cameracomponent with optional QR scanning would cover the most common camera needs out of the box, with proper server-side integration and Lumo theming.Prior art
MediaDevices.getUserMedia()— the underlying web standard, now universally supportedCamera(photo capture via<p:camera>)cordova-plugin-qrscanner, phone camera pluginsImplementation notes
The component would wrap a
<video>element fed bygetUserMedia(). For QR scanning, a lightweight decoder (e.g.jsQRor@zxing/browser) would analyze video frames on the client and emit decoded values to the server via Vaadin's RPC. Photo capture would draw the current video frame to a<canvas>and encode it server-side. All browser permission prompts and error states would be surfaced as server-side events.Accessibility & privacy
stop()) when no longer needed to protect user privacy.I'd be happy to help refine the API. Is this something the team would consider for Vaadin 26?