Shadcn registry
Install editable Video.js React or HTML skins with Tailwind CSS or vanilla CSS
Use the Video.js Shadcn registry when your application should own and edit its skin source. The registry provides skin blocks for React and HTML, Tailwind CSS 4 and vanilla CSS, plus individual styled React UI components.
Players and media remain package imports. A skin block accepts media as children, so you can combine it with any compatible media implementation without generating every Player and media combination.
Initialize Shadcn
Initialize Shadcn if the project does not have a components.json file:
pnpm dlx shadcn@latest init
Add the @videojs namespace for your framework and styling choice:
| Catalog | Namespace URL |
|---|---|
| React + Tailwind | https://shadcn.videojs.org/r/react/{name}.json |
| React + CSS | https://shadcn.videojs.org/r/react/css/{name}.json |
| HTML + Tailwind | https://shadcn.videojs.org/r/html/{name}.json |
| HTML + CSS | https://shadcn.videojs.org/r/html/css/{name}.json |
For example, a React + Tailwind project adds this to components.json:
{
"registries": {
"@videojs": "https://shadcn.videojs.org/r/react/{name}.json"
}
}
The public host will serve these paths when the registry launches. Repository tests exercise the same paths against a local static server.
Install a skin
Install the Default Video Skin:
pnpm dlx shadcn@latest add @videojs/video
Install Minimal Video instead:
pnpm dlx shadcn@latest add @videojs/video-minimal
Default names have no suffix. Minimal is a distinct skin block because its layout differs, while shared UI components and theme primitives keep stable names and paths. Framework and styling are selected by the namespace URL, not repeated in item names.
Shadcn places the installed source under components/videojs/. For example, Video Skin installs to components/videojs/skins/video/; Minimal Video Skin installs to components/videojs/skins/video/minimal/. Shared UI dependencies install under components/videojs/ui/.
React composition
import { HlsJsVideo } from '@videojs/react/media/hlsjs-video';
import { VideoPlayer } from '@videojs/react/video';
import { DefaultVideoSkin } from '@/components/videojs/skins/video/skin';
export function Player({ src }: { src: string }) {
return (
<VideoPlayer>
<DefaultVideoSkin className="aspect-video w-full">
<HlsJsVideo src={src} />
</DefaultVideoSkin>
</VideoPlayer>
);
}HTML composition
<script type="module">
import '@videojs/html/video/player';
import '@videojs/html/media/hls-video';
import './components/videojs/skins/video/skin.ts';
</script>
<video-player>
<!-- Paste the installed skin.html markup here. -->
<hls-video src="https://example.com/video.m3u8"></hls-video>
</video-player>HTML skin blocks keep the copy-owned light-DOM markup explicit. They do not hide it behind a runtime skin element.
Install one React component
React catalogs also publish individual styled UI components:
pnpm dlx shadcn@latest add @videojs/play-button
import { PlayButton } from '@/components/videojs/ui/play-button';Each component imports its own shared component and style dependencies. CSS installs reuse stable concern files such as styles/buttons.css; adding another button does not install a second copy or require a global stylesheet edit. Tailwind components use the project’s existing Tailwind build and the installed Video.js theme definitions.
Inspect and update source
The standard Shadcn commands work with the namespace:
pnpm dlx shadcn@latest search @videojs --query volume
pnpm dlx shadcn@latest view @videojs/volume-popover
pnpm dlx shadcn@latest add @videojs/volume-popover --dry-run
pnpm dlx shadcn@latest add @videojs/volume-popover --diffInstalled files belong to your application. Review the diff before replacing customized source. Do not use --overwrite without reviewing that diff.
Registry catalog
The links below open the exact item JSON consumed by Shadcn.
Skin blocks
Skin blocks install editable UI source for the current React docs. Players and media remain direct package imports.
| Item | Registry |
|---|---|
Default Audio Skin @videojs/audio | View JSON |
Minimal Audio Skin @videojs/audio-minimal | View JSON |
Default Live Audio Skin @videojs/live-audio | View JSON |
Minimal Live Audio Skin @videojs/live-audio-minimal | View JSON |
Default Live Video Skin @videojs/live-video | View JSON |
Minimal Live Video Skin @videojs/live-video-minimal | View JSON |
Default Video Skin @videojs/video | View JSON |
Minimal Video Skin @videojs/video-minimal | View JSON |
| Item | Registry |
|---|---|
Default Audio Skin @videojs/audio | View JSON |
Minimal Audio Skin @videojs/audio-minimal | View JSON |
Default Live Audio Skin @videojs/live-audio | View JSON |
Minimal Live Audio Skin @videojs/live-audio-minimal | View JSON |
Default Live Video Skin @videojs/live-video | View JSON |
Minimal Live Video Skin @videojs/live-video-minimal | View JSON |
Default Video Skin @videojs/video | View JSON |
Minimal Video Skin @videojs/video-minimal | View JSON |
React UI components
Individual React UI components install to stable paths under components/videojs/ui. Choose the styling catalog used by your project.
| Item | Registry |
|---|---|
AirPlay Button @videojs/airplay-button | View JSON |
Audio Track Menu @videojs/audio-track-menu | View JSON |
Buffering Indicator @videojs/buffering-indicator | View JSON |
Button @videojs/button | View JSON |
Captions Button @videojs/captions-button | View JSON |
Captions Menu @videojs/captions-menu | View JSON |
Captions Submenu @videojs/captions-submenu | View JSON |
Cast Button @videojs/cast-button | View JSON |
Container @videojs/container | View JSON |
Error Dialog @videojs/error-dialog | View JSON |
Fullscreen Button @videojs/fullscreen-button | View JSON |
Live Button @videojs/live-button | View JSON |
Mute Button @videojs/mute-button | View JSON |
Picture-in-Picture Button @videojs/pip-button | View JSON |
Play Button @videojs/play-button | View JSON |
Playback Rate Button @videojs/playback-rate-button | View JSON |
Playback Rate Submenu @videojs/playback-rate-submenu | View JSON |
Poster @videojs/poster | View JSON |
Quality Menu @videojs/quality-menu | View JSON |
Radio Item @videojs/radio-item | View JSON |
Seek Button @videojs/seek-button | View JSON |
Seek Indicator @videojs/seek-indicator | View JSON |
Settings Menu @videojs/settings-menu | View JSON |
Slider Parts @videojs/slider | View JSON |
Status Announcer @videojs/status-announcer | View JSON |
Status Indicator @videojs/status-indicator | View JSON |
Time Slider @videojs/time-slider | View JSON |
Volume Indicator @videojs/volume-indicator | View JSON |
Volume Control @videojs/volume-popover | View JSON |
Volume Slider @videojs/volume-slider | View JSON |
| Item | Registry |
|---|---|
AirPlay Button @videojs/airplay-button | View JSON |
Audio Track Menu @videojs/audio-track-menu | View JSON |
Buffering Indicator @videojs/buffering-indicator | View JSON |
Button @videojs/button | View JSON |
Captions Button @videojs/captions-button | View JSON |
Captions Menu @videojs/captions-menu | View JSON |
Captions Submenu @videojs/captions-submenu | View JSON |
Cast Button @videojs/cast-button | View JSON |
Container @videojs/container | View JSON |
Error Dialog @videojs/error-dialog | View JSON |
Fullscreen Button @videojs/fullscreen-button | View JSON |
Live Button @videojs/live-button | View JSON |
Mute Button @videojs/mute-button | View JSON |
Picture-in-Picture Button @videojs/pip-button | View JSON |
Play Button @videojs/play-button | View JSON |
Playback Rate Button @videojs/playback-rate-button | View JSON |
Playback Rate Submenu @videojs/playback-rate-submenu | View JSON |
Poster @videojs/poster | View JSON |
Quality Menu @videojs/quality-menu | View JSON |
Radio Item @videojs/radio-item | View JSON |
Seek Button @videojs/seek-button | View JSON |
Seek Indicator @videojs/seek-indicator | View JSON |
Settings Menu @videojs/settings-menu | View JSON |
Slider Parts @videojs/slider | View JSON |
Status Announcer @videojs/status-announcer | View JSON |
Status Indicator @videojs/status-indicator | View JSON |
Time Slider @videojs/time-slider | View JSON |
Volume Indicator @videojs/volume-indicator | View JSON |
Volume Control @videojs/volume-popover | View JSON |
Volume Slider @videojs/volume-slider | View JSON |