npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@sigx/lynx-camera

v0.26.0

Published

Camera capture for sigx-lynx

Downloads

2,646

Readme

@sigx/lynx-camera

Photo & video capture via the system camera for sigx-lynx. iOS uses UIImagePickerController; Android uses an ACTION_IMAGE_CAPTURE / ACTION_VIDEO_CAPTURE intent fed by a FileProvider URI (the cache-path is wired by the app template's manifest).

📚 Documentation

Full guides, API reference and live examples → https://sigx.dev/lynx/modules/camera/overview/

Install

pnpm add @sigx/lynx-camera

sigx prebuild auto-discovers the package, links the native module, injects android.permission.CAMERA, and adds the iOS usage descriptions:

  • NSCameraUsageDescription
  • NSMicrophoneUsageDescription
  • NSPhotoLibraryAddUsageDescription Override the prompts in your signalx.config.ts under ios.usageDescriptions if you want app-specific copy:
// signalx.config.ts
export default defineLynxConfig({
    ios: {
        usageDescriptions: {
            NSCameraUsageDescription: 'Acme uses the camera to scan QR codes.',
        },
    },
});

On Android the runtime permission prompt + Activity Result wiring comes from @sigx/lynx-permissions, a dependency of this package — the auto-linker pulls it in, nothing to install.

Usage

import { Camera } from '@sigx/lynx-camera';
const { status } = await Camera.requestPermission();
if (status === 'granted') {
    try {
        const photo = await Camera.takePicture({ quality: 0.8, facing: 'back' });
        if (photo.uri) console.log(photo.uri, photo.width, photo.height);
        // else: the user cancelled (resolves with `{ cancelled: true }`)

        // Record a clip — the returned URI loads directly in @sigx/lynx-video.
        const clip = await Camera.recordVideo({ maxDurationMs: 30_000 });
        if (clip.uri) console.log(clip.uri, clip.durationMs);
    } catch (e) {
        // Failure (permission denied, no camera, …) rejects.
        console.warn('capture failed:', e);
    }
}

Each capture has three outcomes: it resolves with a result (always carrying a uri), resolves with { cancelled: true } (no uri) if the user dismisses the camera, or throws on failure. Narrow on result.uri and wrap in try/catch.

API

| Method | Notes | | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | | takePicture(options?: CameraOptions): Promise<PhotoResult \| CameraCancelled> | Opens the system camera in photo mode. Resolves with the captured photo's URI (plus dimensions where available — iOS only), or { cancelled: true } on cancel; throws on failure. | | recordVideo(options?: CameraVideoOptions): Promise<VideoResult \| CameraCancelled> | Opens the system camera in video mode. Resolves with the recorded clip's URI (file:// on iOS, content:// on Android) loadable by @sigx/lynx-video, or { cancelled: true } on cancel; throws on failure. | | requestPermission(): Promise<PermissionResponse> | Shows the OS permission dialog if needed. Re-call to surface the dialog again on first denial. | | getPermissionStatus(): Promise<PermissionResponse> | Read-only check — no prompt. | | isAvailable(): boolean | Whether the native module is registered in the current build. |

interface CameraOptions {        // Android's intent ignores all of these
    facing?: 'front' | 'back';   // iOS only; default: 'back'
    quality?: number;            // iOS only; 0..1 (default 0.8)
    maxWidth?: number;           // reserved — not yet applied on either platform
    maxHeight?: number;          // reserved — not yet applied on either platform
}
interface PhotoResult {
    uri: string;        // file:// (iOS) or content:// (Android)
    width?: number;     // iOS only — Android's intent doesn't report dimensions
    height?: number;    // iOS only
    fileSize?: number;  // iOS only
    base64?: string;    // populated only if requested
}
interface CameraVideoOptions {  // all iOS-only — Android's intent ignores options
    facing?: 'front' | 'back';   // default: 'back'
    maxDurationMs?: number;      // iOS only — Android's intent has no duration cap
}
interface VideoResult {
    uri: string;          // file:// (iOS) or content:// (Android)
    durationMs?: number;  // reported where the platform provides it
    width?: number;
    height?: number;
    fileSize?: number;
}
interface CameraCancelled {
    cancelled: true;
    uri?: undefined;      // present so callers can narrow on `result.uri`
}

Gotchas

  • Permission is auto-requestedtakePicture / recordVideo request the camera permission for you before opening the camera (iOS via AVCaptureDevice; Android via the runtime CAMERA prompt, plus microphone for recordVideo when the app declares RECORD_AUDIO). Calling requestPermission() first is optional — useful only to gate UI on the status ahead of time. On Android it's also required internally: the manifest declares CAMERA, and the OS refuses ACTION_IMAGE_CAPTURE / ACTION_VIDEO_CAPTURE unless it's been granted.
  • Android FileProvider — the auto-injected <provider> in the app template's AndroidManifest.xml exposes the cache directory under ${applicationId}.fileprovider. If you customize the manifest, keep that authority intact or the camera intent won't have a valid write target.
  • iOS simulator camera — the simulator has no real camera, so takePicture / recordVideo report "Camera not available". Test capture on a physical device.
  • Options are honored on iOS only — Android delegates to the system camera intent, which ignores CameraOptions / CameraVideoOptions entirely (the user can still switch cameras in its UI; just don't rely on facing to pick one programmatically on Android). On iOS, facing, quality, and maxDurationMs (video) are applied; maxWidth / maxHeight are reserved and not yet applied on either platform.
  • A single in-camera photo/video toggle (one screen, switch mode in-camera) is iOS-only at the system level; Android has separate photo/video intents. Present your own chooser (Take Photo / Record Video) for a consistent cross-platform flow — see examples/showcase's MediaCaptureCard. An iOS-native capture({ mediaType: 'mixed' }) toggle may be added later.