Open-source embeddable video player

One script tag. A video player that converts.

Embed YouTube, Vimeo, MP4 or HLS on any page — then brand it, add CTAs, capture leads and track every play. Every feature is a plugin. Framework-free, MIT, under 50 KB.

Or download the MIT bundle and self-host it

Show, don't tell

Every feature is a plugin. Scroll to stack them.

The player below is a real, running <player-stack> embedded on this page — not a video of one. As you scroll, each plugin switches on and the config updates live.

  1. sources

    Paste a URL. It just works.

    Point src at a YouTube, Vimeo, MP4 or HLS link. Playerstack detects the type and mounts the matching engine underneath — no per-source code.

    <player-stacksrc="…/demo.mp4"></player-stack>
  2. branded-thumb

    Own the first frame.

    Show a custom poster and load the video only on click — better LCP, and zero third-party cookies until the visitor opts in.

    data-config='{"brandedThumb": {"enabled": true,"clickToLoad": true}}'
  3. controls

    Match your brand in one line.

    A single accent color themes the whole player — play button, progress bar, controls. Here it switches from the default to a brand violet.

    data-config='{"brandedThumb": { … },"controls": {"accent": "#8b5cf6"}}'
  4. cta-end

    Turn the end screen into a CTA.

    When the video ends, overlay a UTM-tagged button with a replay option. The end of the watch becomes the start of a click.

    data-config='{"controls": { … },"ctaEnd": {"enabled": true,"title": "Want the full course?","button": { "label": "Get it now" }}}'
  5. email-gate

    Gate it behind an email.

    Pause playback and ask for an email before the video plays. Open mode emits an event; production mode POSTs to your endpoint with proof-of-work.

    data-config='{"controls": { … },"emailGate": {"enabled": true,"at": "before","title": "Drop your email to watch"}}'

One element, one config object, five plugins shown live. Mix any of the 17 below — or write your own.

One src attribute

Every source, one API.

Playerstack wraps the Mux media ecosystem, so each source exposes a real <video>-style API. Autoplay policy, native events and DOM attributes work the same everywhere.

  • YouTube
  • Vimeo
  • Wistia
  • Twitch
  • Bunny Stream
  • MP4
  • HLS
  • WebM

17 plugins, all MIT

A plugin for every job. Ship only what you use.

The standalone bundle pre-registers everything. Need lean? The codebase is split into scoped @playerstack/* packages, so you can bundle just the plugins you touch.

Marketing

Intro card

@playerstack/plugin-intro-card

Pre-roll splash: badge, title, subtitle, CTA and a big play button.

Branded thumbnail

@playerstack/plugin-branded-thumb

Custom poster + click-to-load for better LCP and GDPR.

End CTA

@playerstack/plugin-cta-end

Overlay a UTM-tagged button when the video ends, with replay.

Action bar

@playerstack/plugin-action-bar

A dismissible mid-video banner with its own call to action.

Email gate

@playerstack/plugin-email-gate

Pause and require an email before playback continues.

YouTube subscribe

@playerstack/plugin-yt-subscribe

A subscribe bar below the player linking to a channel.

Autopreview

@playerstack/plugin-autopreview

Muted autoplay in view, paused out — respects reduced-motion.

E-learning

Chapters

@playerstack/plugin-chapters

A clickable chapter list that syncs with playback.

Saved position

@playerstack/plugin-saved-position

Resume from where the visitor left off.

Focus mode

@playerstack/plugin-focus-mode

Auto-pause when the tab loses focus.

Performance & UX

Sources

@playerstack/plugin-sources

Auto-detect YouTube, Vimeo, MP4, HLS, WebM and DASH from one URL.

Controls policy

@playerstack/plugin-controls-policy

Accent theme plus a whitelist for which controls show.

Sticky

@playerstack/plugin-sticky

Pin to a corner when scrolled past during playback.

Branding

Watermark

@playerstack/plugin-watermark

A corner-pinned logo or text overlay, optional click-through.

Custom CSS

@playerstack/plugin-custom-css

Inject scoped CSS — the escape hatch for anything else.

Analytics & integrations

Analytics

@playerstack/plugin-analytics

Forward events to a beacon endpoint or GA4 via gtag.

Config adapter

@playerstack/plugin-sellf-adapter

Load player config from a remote product endpoint.

Why Playerstack

The marketing layer, without the lock-in.

Engines stop at playback

Developer-focused players nail playback, but branding, CTAs and lead capture are left for you to build. You ship plumbing instead of features.

Funnel players lock you in

The players that do have a marketing layer live inside a single platform you must adopt wholesale — one CMS, one stack, one way.

Playerstack is both, anywhere

A modern Web Component you drop on any page: the marketing layer of the first kind, the openness of the second. MIT, framework-free, yours to extend.

Works where you do

It's a custom element. It runs everywhere.

Because it's a standard Web Component, there's nothing to wrap. Copy-paste examples ship for every common stack.

  • Vanilla HTML
  • React
  • Vue
  • Astro
  • Next.js
  • Tailwind
  • WordPress
  • Multi-instance
  • Click-to-load
  • Analytics
  • Custom plugin
  • Remote config
<script src="https://playerstack.techskills.academy/playerstack.min.js" defer></script>

<player-stack
  src="https://youtu.be/dQw4w9WgXcQ"
  data-config='{"controls":{"accent":"#008aff"},
    "ctaEnd":{"enabled":true,
      "button":{"label":"Buy now","url":"https://example.com"}}}'>
</player-stack>
MIT Core + all 17 plugins
< 50 KB Standalone bundle, gzipped
0 deps to start — one script tag
Mux media-chrome engine, never forked

Questions

The short answers.

Is it really free for commercial use?

Yes. The core and all 17 plugins are MIT-licensed. Use it in client work, products and SaaS without a license fee.

Does it work with my framework?

It's a standard custom element, so it works with plain HTML and with React, Vue, Svelte, Astro, Next.js or anything that renders HTML. Examples ship for each.

What about GDPR and cookies?

The branded-thumbnail plugin loads the video only on click, so no third-party cookies are set until the visitor opts in. That also improves your LCP.

How big is it?

The standalone bundle stays under 50 KB gzipped with every source type and plugin. Need less? The scoped @playerstack/* packages let you bundle only what you use.

How do plugins work?

Each plugin gets an init(ctx) with an event bus, the media element, the container and the resolved config. Write your own in a few lines with the same contract.

Ship it

Add a real video player in one line.

Drop the script tag, add a <player-stack>, and configure it with one attribute. Everything else is a plugin.