Skip to main content
Solid Primitives 2

Primitives to work with media streams from microphones, cameras, and the screen

StageCategoryVersionLast UpdatedDemo
3Browser APIs1.0.0-next.2 (next)Aug 12, 2026Demo →
Terminal window
npm i @solid-primitives/mediastream@next

Reactive primitives for working with MediaStream — microphones, cameras, and screen capture.

Primitives

createStream

Creates a reactive accessor for a MediaStream from a camera or microphone.

const [stream, { mute, stop }] = createStream(streamSource);

Parameters

  • streamSourceMediaDeviceInfo | MediaStreamConstraints | Accessor<...> | FalsyValue

Returns

  • stream()Accessor<MediaStream | undefined> — the current stream (undefined while loading or stopped)
  • mute(muted?) — mutes the stream; pass false to unmute
  • stop() — stops the stream immediately

The stream stops automatically when the reactive owner is disposed. Wrap in <Loading> to handle the loading state:

import { Loading } from "@solidjs/web";
const [stream] = createStream({ video: true });
<Loading fallback={<p>Requesting camera...</p>}>
<video
ref={el =>
createEffect(stream, s => {
el.srcObject = s ?? null;
})
}
autoplay
/>
</Loading>;

createScreen

Creates a reactive accessor for a display capture stream (screen, window, or browser tab).

const [stream, { mute, stop }] = createScreen(screenSource);

Parameters

  • screenSourceDisplayMediaStreamConstraints | undefined | Accessor<DisplayMediaStreamConstraints | undefined>

Same controls as createStream but uses getDisplayMedia instead of getUserMedia. The stream stops automatically when the reactive owner is disposed.

const [stream] = createScreen({ video: true });
<Loading fallback={<p>Requesting screen capture...</p>}>
<video
ref={el =>
createEffect(stream, s => {
el.srcObject = s ?? null;
})
}
autoplay
/>
</Loading>;

createAmplitudeStream

Creates a reactive signal with the RMS amplitude (0–100) from a microphone device.

const [amplitude, { stream, stop }] = createAmplitudeStream(streamSource?);

Parameters

  • streamSource? — same as createStream (optional)

Returns

  • amplitude()Accessor<number> — value between 0 and 100
  • streamAccessor<MediaStream | undefined> — the underlying stream
  • stop() — stops the amplitude measurement and underlying stream
const [audioConstraints, setAudioConstraints] = createSignal<MediaStreamConstraints>();
const [level] = createAmplitudeStream(audioConstraints);
<Show
when={audioConstraints()}
fallback={<button onClick={() => setAudioConstraints({ audio: true })}>Start</button>}
>
<meter min="0" max="100" value={level()} />
</Show>;

createAmplitudeFromStream

Creates an amplitude signal from an existing stream accessor.

const [amplitude, stop] = createAmplitudeFromStream(stream);

Parameters

  • streamMaybeAccessor<MediaStream | undefined>

Returns

  • amplitude()Accessor<number> — value between 0 and 100
  • stop() — stops the amplitude measurement

The measurement stops automatically when the reactive owner is disposed.

createMediaPermissionRequest

Requests media permissions from the user by briefly opening then immediately stopping a stream.

createMediaPermissionRequest(source?);

Parameters

  • source?'audio' | 'video' | MediaStreamConstraints — defaults to both audio and video

Returns a Promise<void> that resolves when permission is granted, and rejects if the user denies permission or navigator.mediaDevices.getUserMedia fails for any other reason — forwarding the rejection directly from getUserMedia.

// Request both microphone and camera permissions
await createMediaPermissionRequest();
// Request only microphone permission
await createMediaPermissionRequest("audio");

Use createPermission from @solid-primitives/permission to reactively observe the resulting permission state.

Breaking Changes from @solid-primitives/stream

This package replaces @solid-primitives/stream with full Solid.js v2 compatibility.

  • createStream / createScreen: return type changed from [Resource<MediaStream>, ResourceActions & { stop, mute }] to [Accessor<MediaStream | undefined>, { stop, mute }]. The mutate and refetch controls are removed; reactivity is driven by the source accessor directly.
  • createAmplitudeStream: return type simplified — second element is now { stream, stop } (no mutate / refetch).
  • isServer: now imported from @solidjs/web internally.
  • Async loading state: use <Loading> from @solidjs/web instead of inspecting stream.loading.
  • Error handling: wrap in <Errored> from @solidjs/web instead of inspecting stream.error.

Changelog

See CHANGELOG.md

Solid Primitives 2High-quality reactive primitives for building applications in Solid2
Community
githubdiscord