<div align="center">

<a href="https://30tools.com">
  <img src="https://img.shields.io/badge/Sponsored%20by-30tools.com-6c5ce7?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0id2hpdGUiPjxwYXRoIGQ9Ik0xMiAyQzYuNDggMiAyIDYuNDggMiAxMnM0LjQ4IDEwIDEwIDEwIDEwLTQuNDggMTAtMTBTMTcuNTIgMiAxMiAyem0wIDE4Yy00LjQxIDAtOC0zLjU5LTgtOHMzLjU5LTggOC04IDggMy41OSA4IDgtMy41OSA4LTggNHoiLz48L3N2Zz4=" alt="Sponsored by 30tools.com" />
</a>

**[30tools.com](https://30tools.com)** — **All Your Tools. One Platform.** 194+ free, privacy-first online tools for Image, PDF, Video, Developer, SEO & more. Fast, beautiful, and no uploads required.

<br/>

# ▶ TanStack Player

**A developer-first, universal Video Player SDK built on Video.js**

Headless hooks · Plugin architecture · React-first DX · Streaming ready

<img src=".github/assets/og-image.png" alt="TanStack Player" width="600" />

[![npm version](https://img.shields.io/npm/v/tanstack?style=flat-square&color=6c5ce7)](https://www.npmjs.com/package/tanstack)
[![npm downloads](https://img.shields.io/npm/dm/tanstack?style=flat-square&color=00d2ff)](https://www.npmjs.com/package/tanstack)
[![npm bundle size](https://img.shields.io/bundlephobia/minzip/tanstack?style=flat-square&color=00e676&label=gzip)](https://bundlephobia.com/package/tanstack)
[![license](https://img.shields.io/npm/l/tanstack?style=flat-square&color=00d2ff)](LICENSE)
[![Visitors](https://api.visitorbadge.io/api/combined?path=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Ftanstack%3FactiveTab%3Dreadme&countColor=%23263759&style=flat&labelStyle=upper)](https://visitorbadge.io/status?path=https%3A%2F%2Fwww.npmjs.com%2Fpackage%2Ftanstack%3FactiveTab%3Dreadme)


[![TypeScript](https://img.shields.io/badge/TypeScript-first-3178C6?style=flat-square&logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
[![Video.js](https://img.shields.io/badge/Video.js-powered-green?style=flat-square)](https://videojs.com/)
[![GitHub stars](https://img.shields.io/github/stars/sh20raj/tanstack?style=flat-square)](https://github.com/sh20raj/tanstack)
[![GitHub issues](https://img.shields.io/github/issues/sh20raj/tanstack?style=flat-square)](https://github.com/sh20raj/tanstack/issues)
[![GitHub pull requests](https://img.shields.io/github/issues-pr/sh20raj/tanstack?style=flat-square)](https://github.com/sh20raj/tanstack/pulls)

[Documentation](https://github.com/sh20raj/tanstack/tree/main/docs) · [npm](https://www.npmjs.com/package/tanstack) · [Examples](https://github.com/sh20raj/tanstack/tree/main/examples) · [Contributing](CONTRIBUTING.md)

</div>

---

## ✨ Why TanStack Player?

Building video experiences is hard — buffering, streaming formats, browser quirks, accessibility, and state management all add complexity. TanStack Player abstracts all of this behind a clean, modern SDK:

| Feature | Description |
|---------|-------------|
| 🎬 **Headless Core** | Framework-agnostic engine with play/pause/seek/volume/speed |
| 🪝 **React Hooks** | `useTanStackPlayer()`, `useProgress()`, `useBookmarks()` |
| 🔌 **Plugin System** | Lifecycle-aware plugins with event bus access |
| 📡 **Streaming** | HLS, DASH, adaptive bitrate via Video.js |
| ⚡ **Tiny** | ~21KB total SDK (ESM, gzipped much smaller) |
| 🎯 **TypeScript** | Full typed API with JSDoc |

---

## 📦 Installation

```bash
npm install tanstack video.js
```

> **Note:** `video.js` is a peer dependency. Load it via CDN or bundle it.

---

## 🚀 Quick Start

```tsx
import { TanStackPlayer } from 'tanstack'

export default function App() {
  return (
    <TanStackPlayer
      src="https://example.com/video.mp4"
      controls
      autoPlay={false}
    />
  )
}
```

---

## 🪝 Hooks API

Build completely custom UI with headless hooks:

```tsx
import { useTanStackPlayer, useProgress } from 'tanstack'

function Controls() {
  const { play, pause, isPlaying, seek, setVolume } = useTanStackPlayer()
  const { progress, buffered, currentTime, duration } = useProgress()

  return (
    <div>
      <button onClick={() => isPlaying ? pause() : play()}>
        {isPlaying ? '⏸' : '▶'}
      </button>
      <div>Progress: {progress.toFixed(1)}%</div>
    </div>
  )
}
```

---

## 🔌 Plugin System

Extend player capabilities with plugins:

```tsx
import { TanStackPlayer, createBookmarkPlugin } from 'tanstack'

const bookmarks = createBookmarkPlugin()

function App() {
  return (
    <TanStackPlayer
      src="/video.mp4"
      plugins={[bookmarks]}
    >
      <BookmarkControls />
    </TanStackPlayer>
  )
}
```

### Using Bookmark Hooks

```tsx
import { useBookmarks } from 'tanstack'

function BookmarkControls() {
  const { bookmarks, addBookmark, seekToBookmark } = useBookmarks()

  return (
    <div>
      <button onClick={() => addBookmark('Important moment')}>
        🔖 Bookmark
      </button>
      {bookmarks.map(bm => (
        <button key={bm.id} onClick={() => seekToBookmark(bm.id)}>
          {bm.label} ({bm.time}s)
        </button>
      ))}
    </div>
  )
}
```

---

## 📦 Packages

| Package | Size | Description |
|---------|------|-------------|
| `tanstack` | — | All-in-one package (re-exports everything) |
| `@tanstack-player/core` | 8.7KB | Headless event bus, state store, controller, plugin runtime |
| `@tanstack-player/adapter-videojs` | 4.6KB | Video.js engine adapter |
| `@tanstack-player/react` | 6.2KB | React component + hooks |
| `@tanstack-player/plugin-bookmark` | 1.6KB | Bookmark plugin |

---

## 🏗 Architecture

```
TanStack Player
 ├─ Core (headless)
 │   ├── EventBus        — typed event emitter
 │   ├── StateStore      — reactive state management
 │   ├── PlayerController — unified playback API
 │   └── PluginRuntime   — plugin lifecycle manager
 │
 ├─ Adapters
 │   └── VideoJsAdapter  — Video.js ↔ Core bridge
 │
 ├─ React
 │   ├── <TanStackPlayer /> — component
 │   ├── useTanStackPlayer  — control hook
 │   ├── useProgress        — progress hook
 │   └── useBookmarks       — bookmark plugin hook
 │
 └─ Plugins
     └── BookmarkPlugin  — timestamp bookmarks
```

---

## ⚙️ Video.js Options

Pass native Video.js configuration through:

```tsx
<TanStackPlayer
  src="/video.mp4"
  videojsOptions={{
    fluid: true,
    preload: 'auto',
    playbackRates: [0.5, 1, 1.5, 2],
  }}
/>
```

---

## 🎯 Events

Unified event system across all adapters:

```tsx
<TanStackPlayer
  src="/video.mp4"
  onReady={() => console.log('Ready!')}
  onPlay={() => console.log('Playing')}
  onPause={() => console.log('Paused')}
  onEnded={() => console.log('Ended')}
  onTimeUpdate={(time, duration) => console.log(`${time}/${duration}`)}
  onError={(err) => console.error(err)}
/>
```

---

## 🛠 Development

```bash
git clone https://github.com/sh20raj/tanstack
cd tanstack
npm install
npm run build
npm run dev
```

See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines.

---

## 🛣 Roadmap

- [ ] HLS.js adapter
- [ ] Plyr lightweight adapter
- [ ] Analytics plugin
- [ ] Floating mini-player plugin
- [ ] Subtitle editor plugin
- [ ] AI chapter detection plugin
- [ ] React Native support

---

## 🧰 Recommended Tools

Looking for developer utilities to use alongside TanStack Player? Check out **[30tools.com](https://30tools.com)** — a suite of **194+ free, privacy-first online tools** for developers:

- **JSON Formatter & Diff Viewer** — perfect for debugging API responses
- **Image Compressor & Converter** — optimize video thumbnails and posters
- **JWT Decoder** — inspect auth tokens for protected video content
- **CSS Gradient Generator** — create beautiful player UI gradients
- **Base64 ↔ Image** — handle inline poster images

All tools run directly in your browser for maximum privacy. No uploads, no tracking.

👉 **[30tools.com](https://30tools.com)** — One platform, every tool you need.

---

## 📄 License

[MIT](LICENSE) — Made with ❤️ by [@sh20raj](https://github.com/sh20raj)

---

<div align="center">

**[⭐ Star on GitHub](https://github.com/sh20raj/tanstack)** — it helps a lot!

</div>
