react-lite-youtube-embed

A privacy-friendly React YouTube embed that loads a thumbnail first and defers the real iframe until the user clicks, keeping bundle weight under 5KB gzipped.

Library
npm
v3.7.0
379stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
83/100Excellent
Development Activity96
Maintenance96
Community60
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
79/100Good
Architecture78
Code Quality88
Innovation66
Learning Curve85

react-lite-youtube-embed is a React port of Paul Irish’s lite-youtube-embed pattern: instead of dropping a full YouTube iframe on the page (which pulls in 500KB+ of scripts before anyone clicks play), it renders a static thumbnail and a play button, and only mounts the real <iframe> once the user interacts with it. That keeps initial page weight and network requests to a minimum, which matters directly for Core Web Vitals and Lighthouse scores on any page that embeds video.

Beyond the lazy-load trick, the component defaults to youtube-nocookie.com so no tracking cookies are set until playback starts, and exposes an enableJsApi mode that wires up YouTube’s postMessage-based IFrame Player API into typed React callbacks (onReady, onStateChange, onPlay, onPause, onEnd, onBuffering, plus playback-rate and quality-change events) so consumers can drive analytics or custom UI off real player state without hand-rolling the postMessage protocol.

It also ships first-class SEO support: an optional seo prop generates schema.org VideoObject JSON-LD structured data, and a noscriptFallback renders a direct YouTube link for crawlers and no-JS clients. Combined with lazy image loading, configurable aspect ratios, playlist support, and full TypeScript types, it functions as a drop-in replacement for a naive iframe embed with meaningfully better performance, privacy, and search characteristics.

What You Get

  • A <LiteYouTubeEmbed> component that renders a clickable thumbnail placeholder and swaps in the real YouTube iframe only on interaction, cutting initial page weight versus a raw embed
  • Privacy-by-default playback via youtube-nocookie.com, with an explicit cookie prop to opt back into the standard cookie-setting domain
  • A typed event system (onReady, onStateChange, onPlay, onPause, onEnd, onBuffering, onPlaybackRateChange, onPlaybackQualityChange) built on YouTube’s postMessage IFrame API, enabled via enableJsApi
  • Built-in SEO tooling: a seo prop that emits schema.org VideoObject JSON-LD, plus an optional <noscript> fallback link for crawlers and non-JS clients
  • Lazy-loaded thumbnails (native loading="lazy"), configurable aspect ratio, poster resolution, playlist mode, and full TypeScript definitions out of the box

Common Use Cases

  • Embedding marketing or product-demo videos on a landing page without tanking Lighthouse/Core Web Vitals scores
  • Adding YouTube video to content-heavy blog or documentation pages where dozens of embeds would otherwise be prohibitively expensive to load eagerly
  • Building privacy-conscious sites (e.g. under GDPR/cookie-consent constraints) that need to avoid setting YouTube tracking cookies until a user opts in by clicking play
  • Wiring video-player state (play/pause/end) into product analytics or custom UI (e.g. auto-advancing a playlist, tracking watch engagement) via the typed event callbacks
  • Publishing video content that needs to surface in Google video rich results, using the built-in JSON-LD structured data support

Under The Hood

Architecture The library is a single-component package: src/lib/index.tsx exports one forwardRef-wrapped functional component, LiteYouTubeEmbedComponent, with all iframe-URL construction, event wiring, and structured-data generation implemented as memoized values and callbacks inside that one component, and a small companion hook (src/lib/useYoutubeThumbnail.tsx) that probes for a maxresdefault thumbnail and falls back to hqdefault if the higher-resolution image fails to load or comes back undersized. State is minimal (preconnected and iframe booleans gating DOM-level warm-up and player mount), and the postMessage listener for enableJsApi mode is set up and torn down in a single useEffect keyed off the iframe/handler props, with retry timeouts to handle YouTube’s asynchronous player-ready signaling. There is no internal module boundary beyond this — it is intentionally a flat, single-purpose component rather than a layered system, since the whole surface area is one piece of interactive DOM behavior.

Tech Stack Built with Vite (vite.config.ts, vite-plugin-dts for type declarations) targeting dual ESM/CJS output (dist/index.es.js, dist/index.cjs) plus a separate CSS file, with React 19 and react-dom as peer dependencies (the library itself has zero runtime dependencies). TypeScript 5.9 in strict mode provides the type surface, ESLint 9 (flat config) plus Prettier enforce style, and size-limit with @size-limit/preset-small-lib gates bundle size in CI (10KB budgets for both ES and CJS builds, 2KB for CSS) — the project visibly treats its small footprint as a first-class constraint, not just a description.

Code Quality Testing is extensive relative to the codebase’s size: src/lib/index.test.tsx runs to over 1,100 lines using Vitest, @testing-library/react, and @testing-library/user-event, covering prop permutations, postMessage event handling, SEO structured-data generation, and accessibility attributes. The ci script chains lint, type-check, test, and build, and GitHub Actions workflows separately enforce CodeQL scanning, a coverage badge, and bundle-size regression checks. Error handling around the postMessage listener explicitly guards against malformed JSON and unexpected origins rather than letting exceptions propagate, and props are fully typed with JSDoc comments documenting defaults and behavior.

What Makes It Unique Rather than just being “a YouTube embed with a placeholder image” (the common pattern popularized by Paul Irish’s vanilla-JS lite-youtube-embed), this port adds a materially deeper feature set on top: typed, ergonomic bindings over YouTube’s raw postMessage IFrame API (most competing React wrappers stop at the click-to-load trick and don’t expose player state at all), first-class schema.org VideoObject JSON-LD generation for SEO, and a documented SLSA Build Level 3 provenance / CodeQL security posture for supply-chain verification — details aimed squarely at production sites that care about both performance and discoverability, not just a demo-quality embed component.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search