extension-camera — Claude Code skill: what it does, how to install
Adds instructions for integrating a React useCamera hook into web apps. Useful for live camera previews and photo capture.
npx skills add caffeinelabs/skills --skill extension-camera -a claude-codeWhat extension-camera does
This skill guides your coding agent on using the prefabricated useCamera hook from the @caffeineai/camera package. The hook handles media stream lifecycles, browser support checks, and structured error types like permission denials or missing devices.
It also enforces strict UI guidelines. The agent binds the stream to a <video> element using videoRef, hides the capture <canvas>, and keeps action buttons disabled until streaming initializes. Photos export directly as File objects with selectable formats (jpeg, png, webp) and quality settings from 0 to 1.
Desktop environments cannot toggle between cameras because only the environment mode functions there. The agent knows this rule and disables camera switching on desktop screens.
What it helps with
- integrate a camera preview using the
useCamerahook - capture and export still photos as
Fileobjects - handle device permission and missing camera errors
- prevent UI clicks before the video stream is ready
Example prompts for the agent
- Create a camera preview component with photo capture using useCamera
- Add camera switching and error handling for web devices
- Build a responsive React component for capturing pictures
How to install extension-camera
1Skills CLI (Vercel)
npx skills add caffeinelabs/skills --skill extension-camera -a claude-code2Manually: put the files in place
~/.claude/skills/extension-camera/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/extension-camera/
1Skills CLI (Vercel)
npx skills add caffeinelabs/skills --skill extension-camera -a codex2Manually: put the files in place
.agents/skills/extension-camera/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add caffeinelabs/skills --skill extension-camera -a cursor2Manually: put the files in place
.cursor/skills/extension-camera/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install caffeinelabs/skills extension-camera2Manually: put the files in place
.github/skills/extension-camera/SKILL.md1Skills CLI (Vercel)
npx skills add caffeinelabs/skills --skill extension-camera -a gemini-cli2Platform CLI
gemini skills install https://github.com/caffeinelabs/skills --path skills/extension-cameraManually: put the files in place
.devin/skills/extension-camera/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add caffeinelabs/skills --skill extension-camera -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about extension-camera
How to install extension-camera in Claude Code?
Run npx skills add caffeinelabs/skills --skill extension-camera -a claude-code in your terminal. This writes the skill to ~/.claude/skills/extension-camera/SKILL.md.
What does extension-camera do?
It provides patterns and rules for building React camera interfaces with @caffeineai/camera. It covers streaming, camera switching, error states, and capturing photos.
What dependencies are required for extension-camera?
The skill relies on the @caffeineai/camera npm package with version ~0.1.1 alongside React.
Source text
SKILL.md · Apache-2.0
---
name: extension-camera
description: Web-camera support.
version: 0.1.4
compatibility:
npm:
"@caffeineai/camera": "~0.1.1"
caffeineai-subscription: [none]
---
# Camera
Camera extension for [Caffeine AI](https://caffeine.ai?utm_source=caffeine-skill&utm_medium=referral).
## Overview
This skill adds web-camera access via a prefabricated React hook. Supports photo capture, camera switching, and error handling.
# Frontend
For camera support:
There is a prefabricated React hook `@caffeinelabs/camera/hooks/useCamera.ts` that cannot be modified.
```typescript filepath=@caffeinelabs/camera/hooks/useCamera.ts
import { RefObject } from 'react';
export interface CameraConfig {
// Camera facing mode - 'user' for front camera, 'environment' for back camera
facingMode?: 'user' | 'environment';
// Ideal video width and height in pixels
width?: number;
height?: number;
// Image quality for capture (0-1, where 1 is highest quality)
quality?: number;
format?: 'image/jpeg' | 'image/png' | 'image/webp';
}
export interface CameraError {
type: 'permission' | 'not-supported' | 'not-found' | 'unknown' | 'timeout';
message: string;
}
export interface UseCameraReturn {
// Whether camera is currently active and streaming
isActive: boolean;
// Whether camera is supported in current browser (null while checking)
isSupported: boolean | null;
// Current error state, if any
error: CameraError | null;
// Whether camera is initializing, starting, switching, or stopping
isLoading: boolean;
currentFacingMode: 'user' | 'environment';
// Returns true on success
startCamera: () => Promise<boolean>;
stopCamera: () => Promise<void>;
capturePhoto: () => Promise<File | null>;
// Returns true on success
switchCamera: () => (newFacingMode?: 'user' | 'environment') : Promise<boolean>;
// Returns true on success
retry: () => Promise<boolean>;
// Ref to attach to video element for camera preview
videoRef: RefObject<HTMLVideoElement>;
// Ref to canvas element used for photo capture (can be hidden)
canvasRef: RefObject<HTMLCanvasElement>;
}
export declare function useCamera(config?: CameraConfig): UseCameraReturn;
```
Usage example:
```
import { useCamera } from '@caffeineai/camera';
function CameraComponent() {
const {
isActive,
isSupported,
error,
isLoading,
startCamera,
stopCamera,
capturePhoto,
switchCamera,
videoRef,
canvasRef
} = useCamera({
autoStart: true,
facingMode: 'environment'
});
if (isSupported === false) {
return <div>Camera not supported</div>;
}
return (
<div>
<video
ref={videoRef}
style={{ width: '100%', height: 'auto' }}
playsInline
muted
/>
<canvas ref={canvasRef} style={{ display: 'none' }} />
{error && <div>Error: {error.message}</div>}
<div>
<button onClick={startCamera} disabled={isLoading || isActive}>
Start Camera
</button>
<button onClick={stopCamera} disabled={isLoading || !isActive}>
Stop Camera
</button>
<button onClick={switchCamera} disabled={isLoading || !isActive}>
Switch Camera
</button>
<button onClick={capturePhoto} disabled={!isActive}>
Take Photo
</button>
</div>
</div>
);
}
```
Always place a capture button on camera preview!
Always show a camera preview when the user opens the camera
On desktop, make sure that camera cannot be switched. Only 'environment' is working.
Properly display camera error messages in the app.
Do not make camera buttons clickable until the camera is fully initialized and ready.
Ensure the camera preview has explicit, non-zero dimensions (fixed height, min-height, or an aspect-ratio wrapper) so it never collapses due to layout.
Make the preview responsive across screen sizes (e.g., width: 100% with a stable aspect ratio).
© caffeinelabs · Apache-2.0 · caffeinelabs/skills