Last Updated: 2025-10-21
Project: TVx - IPTV + EPG Viewer with CRT Nostalgia
Repository: dopeytree/TVx
Branch:main
TVx is a client-side web application that provides a nostalgic CRT-style interface for viewing IPTV streams with EPG (Electronic Program Guide) data. It's designed for Tunarr (Plex/Jellyfin) playlists and XMLTV guides, focusing on channel surfing rather than catalog browsing.
- Anti-algorithm television experience
- Vintage CRT aesthetic (scanlines, curvature, chromatic aberration)
- Instant channel surfing with keyboard shortcuts
- Full TV guide integration with poster artwork
- Theater viewing modes
- Frontend: React 18 + TypeScript
- Build Tool: Vite 5
- Styling: Tailwind CSS + Radix UI components
- Video Streaming: HLS.js for adaptive streaming
- Visual Effects: WebGL Fragment Shaders for CRT effects
- State Management: React hooks + context
- Icons: Lucide React
/Users/ed/TVx/
βββ src/
β βββ components/ # React components (ChannelList, EPGView, VideoPlayer, etc.)
β βββ hooks/ # Custom React hooks (useSettings, useKeyboardShortcuts)
β βββ pages/ # Page components (Index, NotFound)
β βββ types/ # TypeScript type definitions
β βββ utils/ # Utilities (m3uParser, xmltvParser, logger)
β βββ App.tsx # Main app component
β βββ main.tsx # Entry point
βββ docs/ # Jekyll documentation site
βββ public/ # Static assets
βββ config/ # Configuration files
βββ .vscode/ # VS Code tasks and settings
βββ Docker files # Dockerfile, docker-compose.yml, nginx.conf
# Install Node.js dependencies
npm install
# Install documentation dependencies (Jekyll)
cd docs && bundle installReference the commands-cheatsheet.json in the project root for frequently used commands. Top commands:
-
Development Server (localhost:5173)
npm run dev
-
Documentation Server (localhost:4000)
cd docs && bundle exec jekyll serve --host 0.0.0.0 --port 4000 --baseurl /TVx
-
Build Production
npm run build
-
Lint Code
npm run lint
-
Docker Build & Run
docker build -t tvx:latest . && docker run -d --name tvx -p 8777:80 \ -e VITE_M3U_URL=http://your-server:8000/api/channels.m3u \ -e VITE_XMLTV_URL=http://your-server:8000/api/xmltv.xml \ tvx:latest
-
Docker Logs
docker logs -f tvx # or with docker-compose docker-compose logs -f tvx
For all test Docker & dev builds, prefill the env variables as:
export VITE_M3U_URL=http://192.168.22.2:8000/api/channels.m3u
export VITE_XMLTV_URL=http://192.168.22.2:8000/api/xmltv.xmlUse Cmd+Shift+P β "Tasks: Run Task" or Cmd+Shift+B for default build task.
Available tasks (see .vscode/tasks.json):
- Serve Documentation
- Run Dev Server (default)
- Watch Docker Logs
- Build Production
- Build Documentation
- Lint Code
- M3U playlist parsing (
src/utils/m3uParser.ts) - Smart channel name formatting (strips filler words, adds emoji icons)
- Channel grouping and organization
- XMLTV parser (
src/utils/xmltvParser.ts) - Full TV guide view with 12-hour timeline
- Program metadata display with poster artwork
- HLS.js adaptive streaming
- Multiple viewing modes (normal, guide, immersive)
- Keyboard shortcuts for navigation
- WebGL shaders for CRT effects
- Configurable vintage filters (scanlines, vignette, chromatic aberration)
- Theater mode toggles
- Comprehensive user interaction logging
- Docker container log output
- Settings persistence via localStorage
- Use strict type checking
- Define interfaces in
src/types/ - Avoid
anytypes when possible - Use descriptive variable/function names
- Functional components with hooks
- Custom hooks in
src/hooks/ - Component-specific styles in
.cssfiles when needed - Use Radix UI for accessible components
- Tailwind CSS utility classes
- Follow existing design patterns (dark theme, neon accents)
- Maintain CRT aesthetic consistency
- Components: One component per file
- Utils: Pure functions, well-documented
- Types: Shared interfaces and types
- Keep related code together
Required for Docker deployment:
VITE_M3U_URL- M3U playlist URL (Tunarr API)VITE_XMLTV_URL- XMLTV EPG URL (Tunarr API)TZ- Timezone (optional, default: UTC)
- Vite builds static files to
dist/ - Nginx serves static content on port 80
- Health checks configured for container monitoring
- Alpine-based image for minimal size
- Docker Hub:
ghcr.io/dopeytree/tvx:latest - Unraid Community Apps
- Self-hosted via Docker Compose
- Jekyll static site in
docs/ - GitHub Pages: https://dopeytree.github.io/TVx/
- Markdown source files with YAML frontmatter
# Local preview
cd docs && bundle exec jekyll serve --host 0.0.0.0 --port 4000 --baseurl /TVx
# Build static site
cd docs && bundle exec jekyll build- Install: Docker, Unraid, prerequisites
- Quick Start: GUI, keyboard shortcuts, screenshots
- Manual: Features, browser support, tech stack, troubleshooting
- Development: Contributing, server setup, bug fixes
- Check if it fits the project philosophy (analog nostalgia, simplicity)
- Create component in
src/components/if UI-related - Add types to
src/types/if new data structures - Update documentation in
docs/manual/ - Test in development server
- Update README.md if user-facing
- Check
docs/development/bug fixes/for known issues - Review Docker logs for error context
- Test fix in dev environment
- Update relevant documentation
- Consider adding to troubleshooting guide
- Edit Markdown files in
docs/ - Preview locally with Jekyll
- Maintain consistent formatting and style
- Update navigation if adding new pages
- Check bundle size after changes (
npm run build) - Optimize images and assets
- Review HLS.js configuration for streaming
- Test on target browsers (Chrome 90+, Firefox 88+, Safari 14+)
- β Maintain the vintage CRT aesthetic
- β Keep the interface simple and intuitive
- β Document all user-facing changes
- β Test keyboard shortcuts thoroughly
- β Ensure Docker builds successfully
- β Follow existing code patterns
- β Add comprehensive logging for debugging
- β Add algorithm-driven features (recommendations, trending, etc.)
- β Break keyboard navigation
- β Remove or significantly alter the CRT effects
- β Add unnecessary dependencies
- β Ignore TypeScript errors
- β Change Docker ports without documentation updates
- β Modify the PolyForm Noncommercial license
- Tunarr: IPTV channel streaming backend
- Plex/Jellyfin: Media server for content metadata
- M3U source: Channel playlist feed
- XMLTV source: EPG data feed
- WebGL for shader effects
- localStorage for settings persistence
- MediaSource Extensions for HLS playback
- Fullscreen API
- Documentation: https://dopeytree.github.io/TVx/
- GitHub Issues: Report bugs or feature requests
- Code Comments: Inline documentation in source files
- README.md: Quick reference and setup guide
README.md- Project overview and quick startcommands-cheatsheet.json- Frequently used commandsdocs/manual/tech-stack.md- Technical architecturedocs/manual/troubleshooting/- Common issues and solutions.vscode/tasks.json- Configured development tasks
- Run linter:
npm run lint - Test build:
npm run build - Verify Docker build:
docker build -t tvx . - Test in target browsers
- Check documentation builds:
cd docs && bundle exec jekyll build
- Channel surfing (up/down arrows)
- EPG guide toggle (G key)
- Fullscreen mode (F key)
- Settings dialog
- Video playback
- CRT effects toggle
- Theater mode cycling
- Mobile responsiveness
TVx is about feeling, not features.
The goal is to recreate the experience of classic television:
- Present and unhurried
- Intentional channel surfing
- Warm, imperfect visuals
- Ritualistic viewing
When making decisions, prioritize:
- Simplicity over feature bloat
- Nostalgia over modern trends
- Moment over metrics
- Analog warmth over digital perfection
PolyForm Noncommercial 1.0.0
- β Free for personal, educational, and non-profit use
- β Can modify and share
- β Cannot use commercially without permission
When contributing, ensure all code is compatible with this license.
# 1. Clone and navigate to project
cd /Users/ed/TVx
# 2. Install dependencies
npm install
# 3. Start dev server
npm run dev
# 4. Start docs server (separate terminal)
cd docs && bundle exec jekyll serve --host 0.0.0.0 --port 4000 --baseurl /TVx
# 5. View in browser
# App: http://localhost:5173
# Docs: http://localhost:4000/TVxReference commands-cheatsheet.json and .vscode/tasks.json for additional workflows.
Happy coding! Keep the analog warmth alive. πΊβ¨