Skip to main content
There are two ways to get a picture from the camera.

Photo with the system camera

number
default:"0.7"
JPEG quality from 0 to 1.
boolean
default:"false"
Show the crop step after capture.
The result is { asset?, cancelled, error? }. asset has uri (a base64 data URL), width, height, fileName and mimeType. error is 'permission_denied' when camera access is refused; permission is requested automatically. In a browser, capture opens a file picker restricted to images. width and height are 0 there.

Photos and video with the camera screen

openCamera opens the shell’s own camera: viewfinder, lens switch, zoom, torch, shutter and a “use / retake” step all belong to the shell. Your page renders nothing and waits for the result, which keeps the capture experience the same in every app.
available starts undefined and settles once the shell answers. Mobile and desktop shells have a camera screen; TV and plain browsers do not.

Options

'photo' | 'video' | 'both'
default:"'photo'"
both takes a photo on tap and records while the shutter is held. Video needs 'video' or 'both', because the camera session has to be set up for it from the start.
'back' | 'front'
The lens to start with. The user can still switch. On desktop this selects between webcams.
number
Recording limit, also shown as a countdown.
number
Size limit in bytes.
string
Text shown over the viewfinder.
Offer “pick from gallery” next to the shutter.
boolean
default:"true"
Record sound in video mode. Requires microphone permission; pass false for silent clips.
'blob' | 'uri'
default:"'blob'"
'uri' skips transferring the video to the page and returns only the shell-side file path.

Result

CameraAsset
Set when the user took a photo. uri is a base64 data URL.
object
boolean
The user closed the camera without keeping anything.
string
permission_denied, microphone_denied, not_available, busy, too_large or failed.
A 60-second clip is roughly 10–20 MB and is transferred to the page in chunks, which can take a second or two. Clips over 64 MB are not transferred: you get error: 'too_large' and only video.nativeUri.
Without hooks: capturePhoto(options), openCamera(options) and isCameraAvailable().