vertical-video-kit
v1.0.0
Published
React components for vertical video feeds like TikTok/Reels
Maintainers
Readme
vertical-video-kit
A React component library for building vertical video feed experiences like TikTok, Instagram Reels, or YouTube Shorts.
Features
- 📱 Optimized for vertical video layouts
- 🔄 Smart video preloading with bandwidth optimization
- 📺 Support for both MP4 and HLS (m3u8) formats
- 🌐 Cross-browser compatibility with HLS.js for non-Safari browsers
- 📦 Lightweight with minimal dependencies
Installation
npm install vertical-video-kit
# or
yarn add vertical-video-kitMake sure to also install the peer dependencies if not already in your project:
npm install react react-dom hls.js
# or
yarn add react react-dom hls.jsUsage
VideoCard Component
The VideoCard component handles video playback with proper lifecycle management:
import { VideoCard } from 'vertical-video-kit';
function VideoItem({ videoUrl, isActive }) {
return (
<div style={{ height: '100vh', width: '100%' }}>
<VideoCard
src={videoUrl}
isActive={isActive}
muted={false}
/>
</div>
);
}useVideoPreload Hook
The useVideoPreload hook optimizes bandwidth by preloading adjacent videos:
import { useVideoPreload, VideoCard } from 'vertical-video-kit';
function VideoFeed() {
const videos = ['video1.mp4', 'video2.mp4', 'video3.mp4'];
const [currentIndex, setCurrentIndex] = useState(0);
// Preload adjacent videos
useVideoPreload(videos, currentIndex);
return (
<div>
{videos.map((video, index) => (
<VideoCard
key={index}
src={video}
isActive={index === currentIndex}
muted={true}
/>
))}
</div>
);
}Complete Example
Here's a complete example of a basic vertical video feed:
import React, { useState, useEffect } from 'react';
import { VideoCard, useVideoPreload } from 'vertical-video-kit';
const VerticalFeed = ({ videos }) => {
const [activeIndex, setActiveIndex] = useState(0);
// Preload adjacent videos
useVideoPreload(videos, activeIndex);
// Handle scroll to determine active video
useEffect(() => {
const handleScroll = () => {
// Simple implementation - in a real app, you'd determine
// which video is most visible in the viewport
const newIndex = Math.floor(window.scrollY / window.innerHeight);
if (newIndex >= 0 && newIndex < videos.length) {
setActiveIndex(newIndex);
}
};
window.addEventListener('scroll', handleScroll);
return () => window.removeEventListener('scroll', handleScroll);
}, [videos.length]);
return (
<div>
{videos.map((videoUrl, index) => (
<div
key={index}
style={{
height: '100vh',
width: '100%',
scrollSnapAlign: 'start'
}}
>
<VideoCard
src={videoUrl}
isActive={index === activeIndex}
muted={false}
/>
</div>
))}
</div>
);
};
export default VerticalFeed;API Reference
VideoCard
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| src | string | required | URL of the video (supports .mp4 and .m3u8) |
| isActive | boolean | required | Whether this video is currently active (plays when true, pauses when false) |
| muted | boolean | true | Whether the video should be muted |
useVideoPreload
useVideoPreload(videoUrls: string[], currentIndex: number)videoUrls: Array of video URLs to managecurrentIndex: Index of the currently active video
License
MIT
