A production-oriented React frontend for a full-stack video streaming platform. PulseStream provides adaptive video playback, authentication, personalized content management, subscriptions, search, and administrative media management through a responsive web interface.
Live Demo: (https://thepulsestream.netlify.app/)
PulseStream is a full-stack streaming platform designed around the core workflows of a modern video-on-demand system.
The frontend is responsible for:
- Content discovery and browsing
- Adaptive video playback
- Authentication and session management
- Watchlist and viewing progress
- Subscription workflows
- Search and content navigation
- Administrative content management
- Responsive user interfaces
The application communicates with a Spring Boot backend through REST APIs.
This repository contains the frontend application. The backend is maintained separately.
- HTTP Live Streaming (HLS) playback
- Adaptive bitrate streaming
- HLS.js-based custom video player
- Video quality selection
- Resume playback from previous progress
- Dedicated watch experience
- Media delivery through cloud object storage
- JWT-based authentication
- Email-based OTP verification
- Google OAuth 2.0 authentication
- Forgot-password workflow
- Automatic JWT expiration detection
- Centralized unauthorized-response handling
- Protected application routes
- Role-based administrative access
- Movie and series browsing
- Structured content categories
- Search with instant suggestions
- Movie, series, season, and episode navigation
- Dynamic content cards and rows
- Responsive content layouts
- Personal watchlist
- Optimistic watchlist updates
- Continue-watching functionality
- Playback progress tracking
- User profile management
- Session-expiration handling
- Razorpay payment integration
- Subscription plan selection
- Upgrade and downgrade workflows
- Subscription status management
- Payment-state handling from the frontend
- Protected admin routes
- Movie and series management
- Poster and banner uploads
- Video upload workflow
- Storage monitoring
- Role-based access control
The frontend follows a modular React architecture with responsibilities separated between UI components, pages, application state, API communication, and authentication workflows.
┌─────────────────────┐
│ React UI │
│ Components / Pages │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Redux Toolkit │
│ Application State │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Axios API Layer │
│ Interceptors/Auth │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Spring Boot API │
│ Backend │
└──────────┬──────────┘
│
┌─────────────────┼──────────────────┐
▼ ▼ ▼
PostgreSQL Cloud Storage Payment API
/ Media Services Razorpay
The frontend does not directly manage core business logic. Authentication, authorization, subscription validation, content persistence, and other business operations are handled by the backend.
| Layer | Technology |
|---|---|
| UI Framework | React 18 |
| Build Tool | Vite 5 |
| Styling | Tailwind CSS 3 + Custom CSS |
| State Management | Redux Toolkit |
| Async State | Redux Thunk |
| HTTP Client | Axios |
| Video Playback | HLS.js |
| Authentication | JWT + Google OAuth 2.0 |
| Payments | Razorpay |
| Notifications | React Hot Toast |
| Icons | React Icons |
| Deployment | Vercel |
src/
│
├── api/
│ └── axiosConfig.js
│ └── Centralized Axios instance,
│ authentication headers and interceptors
│
├── Components/
│ │
│ ├── browse/
│ │ ├── MovieCard
│ │ ├── ContentRow
│ │ └── Browse components
│ │
│ ├── common/
│ │ ├── Navbar
│ │ ├── Modal
│ │ ├── Footer
│ │ └── Toaster
│ │
│ ├── layout/
│ │ ├── GlassNavbar
│ │ └── PrivateRoute
│ │
│ └── video/
│ └── PulsePlayer
│
├── pages/
│ ├── Auth.jsx
│ ├── Home.jsx
│ ├── Watch.jsx
│ ├── Profile.jsx
│ ├── Subscription.jsx
│ ├── MyWatchlist.jsx
│ ├── Content.jsx
│ ├── SessionExpired.jsx
│ └── OAuth2RedirectHandler.jsx
│
├── store/
│ │
│ ├── slices/
│ │ ├── authSlice.js
│ │ ├── contentSlice.js
│ │ └── watchlistSlice.js
│ │
│ └── actions/
│ └── authActions.js
│
└── App.jsx
PulseStream uses JWT-based authentication for normal application access and Google OAuth 2.0 for social authentication.
User
│
▼
Login / Signup
│
▼
Spring Boot API
│
▼
JWT issued
│
▼
Frontend stores authentication state
│
▼
Axios attaches token to protected requests
│
▼
Backend validates JWT
The frontend also validates the token's exp claim when restoring a session. Expired tokens are removed before the application considers the user authenticated.
Google authentication is handled through the backend's OAuth2 flow.
After authentication:
Google
│
▼
Spring Security OAuth2
│
▼
Backend
│
▼
OAuth Redirect
│
▼
OAuth2RedirectHandler
│
▼
Authentication State
The redirect handler removes the token from the browser URL immediately after processing to prevent unnecessary exposure in the address bar and browser history.
Session handling is centralized through the Axios interceptor and application-level session listener.
API Request
│
▼
Spring Boot
│
├── 200 ──► Continue normally
│
└── 401
│
▼
Axios Interceptor
│
▼
auth:session-expired event
│
▼
App.jsx
│
├── Logout
├── Clear Watchlist
└── Navigate to /session-expired
Authentication routes such as /auth/* and OAuth endpoints are excluded from the session-expiration mechanism so invalid login credentials do not incorrectly trigger a session-expired state.
The application uses HLS.js to consume HLS streams generated and stored by the backend infrastructure.
The playback flow is approximately:
User opens Watch page
│
▼
Frontend requests stream information
│
▼
Backend authorizes content access
│
▼
HLS manifest returned
│
▼
HLS.js initializes
│
▼
.m3u8 manifest
│
▼
Video segments
│
▼
Adaptive playback
HLS allows the player to dynamically select appropriate video quality based on available bandwidth and playback conditions.
Redux Toolkit is used for application-level state that needs to be shared across multiple parts of the application.
Responsible for:
- Current authenticated user
- JWT state
- Session restoration
- Token expiration validation
- Login/logout state
Responsible for:
- Movies
- Series
- Seasons
- Episodes
- Content loading states
- Content-related API operations
Responsible for:
- Current user's watchlist
- Adding content
- Removing content
- Optimistic UI updates
- Watchlist synchronization
This separation prevents individual components from becoming responsible for global application state.
Watchlist operations use optimistic UI updates where appropriate.
Instead of waiting for the backend before updating the interface:
User clicks "Add to Watchlist"
│
▼
UI updates immediately
│
▼
API request sent
│
┌────┴────┐
▼ ▼
Success Failure
│ │
▼ ▼
Keep state Rollback
This makes interactions feel immediate while maintaining synchronization with the backend.
The frontend implements several mechanisms to improve session reliability and reduce common client-side authentication issues.
| Concern | Implementation |
|---|---|
| JWT expiration | exp claim checked during session restoration |
| Unauthorized requests | Centralized Axios interceptor |
| Session cleanup | Global session-expired event |
| Protected pages | Private route handling |
| Admin access | Role-aware frontend routes |
| OAuth token exposure | Token removed from redirect URL |
| Authentication logging | Tokens are not logged |
| Authentication routes | Excluded from generic 401 handling |
Client-side authorization is not treated as a security boundary. Sensitive authorization decisions must always be enforced by the backend.
Create a .env file in the project root:
VITE_BACK_END_URL=http://localhost:8080
VITE_RAZORPAY_KEY_ID=rzp_test_xxxxxxxxx
VITE_TMDB_API_KEY=your_tmdb_api_key| Variable | Purpose |
|---|---|
VITE_BACK_END_URL |
Spring Boot backend URL |
VITE_RAZORPAY_KEY_ID |
Razorpay public/test key |
VITE_TMDB_API_KEY |
TMDB API access for fallback metadata/images |
Do not commit private credentials or secrets to the repository.
- Node.js 18+
- npm
- Running PulseStream Spring Boot backend
- Required environment variables
git clone https://github.com/yourusername/PulseStreamFrontend.git
cd PulseStreamFrontend/pulsestream-frontendnpm installnpm run devThe application will be available at:
http://localhost:5173
npm run buildnpm run previewThe frontend is a Vite-generated static application and can be deployed to platforms such as Vercel or other static hosting providers.
Production deployment requires the appropriate environment variables to be configured in the hosting platform.
npm run buildThe generated production assets are placed inside:
/dist
PulseStream Frontend is designed to work with a Spring Boot backend responsible for:
- Authentication
- User management
- Content management
- Authorization
- Watchlist persistence
- Playback progress
- Subscription management
- Media processing/storage
- REST API endpoints
The frontend communicates with these services through the centralized Axios configuration.
The project demonstrates practical implementation of:
- React component architecture
- Global state management with Redux Toolkit
- REST API integration
- Axios request/response interceptors
- JWT authentication
- OAuth2 authentication
- Protected routes
- Role-based UI access
- HLS adaptive video streaming
- Optimistic UI updates
- Subscription/payment workflows
- Cloud media integration
- Responsive UI development
- Production deployment
- Client-side session lifecycle management
Potential areas for further development include:
- Automated frontend testing
- End-to-end testing
- Improved accessibility
- Progressive Web App support
- Advanced playback analytics
- Better caching strategies
- Skeleton loading states across all content views
- Internationalization
- Improved error boundaries
- Performance monitoring
- CDN-aware media delivery
- Automated CI/CD pipelines
Contributions, issues, and feature requests are welcome.
# Create a feature branch
git checkout -b feature/your-feature
# Make your changes
# Commit
git commit -m "feat: add your feature"
# Push
git push origin feature/your-featureThen open a pull request describing the changes.
This project is distributed under the MIT License.
See LICENSE for details.