Skip to content
FrameworkStyle

Self-host the player

Serve the Video.js HTML player from your own origin for offline, air-gapped, or restricted-network deployments

By default, the installation flow loads the player from a public CDN. For offline, air-gapped, or locked-down deployments, you can serve everything from your own origin instead. Pick one of the options below.

Install the package, put the player’s imports into an entry file, then let any bundler produce one self-contained module you can host anywhere. For the default video player, that’s:

import '@videojs/html/video/player';
import '@videojs/html/video/skin';
npm install @videojs/html
npx esbuild player.js --bundle --format=esm --minify --sourcemap --outfile=public/player.js

Load the output with type="module":

<script type="module" src="/player.js"></script>

You get one file (plus a sourcemap), no runtime requests to a CDN, and only the features you import. Any bundler works (Vite, Rollup, webpack) as long as the output stays ESM.

Mirror the prebuilt CDN files

To skip the bundler, copy the prebuilt CDN bundle to your server as-is.

npm install @videojs/html
mkdir -p public
cp -r node_modules/@videojs/html/cdn public/videojs

Then point the script tag at your copy instead of the CDN:

<script type="module" src="/videojs/video.js"></script>

The file name matches your player: video.js, audio.js, background.js, and so on. Every option is present in the cdn/ folder you copied.

Hashed chunk names change between releases, so re-copy the directory whenever you upgrade @videojs/html.

HLS and other media types

HLS and other non-default media need their own module on top of the player. Match it in your self-hosted build:

  • Bundle: add the media import to your entry file (import '@videojs/html/media/hls-video';) and use the matching <hls-video> element with your .m3u8 source.
  • Mirror: serve the media file too and add its script tag (<script type="module" src="/videojs/media/hls-video.js"></script>).

Without the media module the player UI renders but the video never loads, with no console error.