PulseVote is a full-stack polling platform that enables users to create polls, cast votes, and visualize results in real time.
Built with Next.js, TypeScript, Prisma, PostgreSQL, Redux Toolkit, and Server-Sent Events (SSE), PulseVote demonstrates modern full-stack application architecture, real-time data synchronization, scalable state management, and interactive data visualization.
🌐 Live Demo: https://pulsevoteapp.vercel.app/
Polling platforms are often limited to collecting responses without providing engaging, real-time feedback to participants.
PulseVote was designed to create a seamless voting experience where users can:
- Create custom polls instantly
- Vote without account registration
- See results update in real time
- Analyze voting trends through interactive charts
- Access polls across desktop and mobile devices
The application combines modern frontend engineering with a robust backend architecture to deliver a responsive and interactive user experience.
Users can create polls by providing:
- Poll title
- Optional description
- Multiple voting options
- Creator display name
Polls are immediately persisted to the database and become available to all users.
PulseVote removes the friction of mandatory account creation.
Instead of traditional authentication:
- A unique guest ID is generated and stored in localStorage
- Returning visitors retain the same identity
- Users can participate instantly
- Vote tracking prevents duplicate voting
This approach provides a streamlined user experience while maintaining poll integrity.
PulseVote uses Server-Sent Events (SSE) to deliver live vote updates.
When a vote is submitted:
- Vote data is stored in PostgreSQL
- Vote counts are updated through Prisma
- The SSE service detects changes
- Connected clients receive update events
- Redux refreshes application state
- Charts re-render automatically
Results update without requiring page refreshes.
Poll results are displayed through dynamic charts powered by Chart.js.
Features include:
- Live vote counts
- Percentage breakdowns
- Responsive visualizations
- Automatic updates during active voting
PulseVote is designed with a mobile-first approach and supports:
- Mobile devices
- Tablets
- Desktop screens
The interface adapts seamlessly across screen sizes.
Redux Toolkit manages:
- Poll collections
- Poll details
- Live voting results
- Loading states
- Error handling
This creates a predictable and scalable state architecture.
Unlike traditional polling applications that require manual refreshes, PulseVote implements a real-time update system using Server-Sent Events (SSE).
For this use case, communication is primarily one-directional:
Server → Client
SSE provides:
- Lower overhead than WebSockets
- Automatic reconnection support
- Simpler implementation
- Native browser support
- Persistent server-to-client updates
PulseVote leverages both Server Components and Client Components.
Used for:
- Initial data fetching
- SEO-friendly rendering
- Database-backed content delivery
Examples:
app/page.tsx
app/poll/[id]/page.tsx
Used for:
- Voting interactions
- Form submissions
- Real-time subscriptions
- Redux integration
Examples:
PollVoteClient
PollCreateForm
PollResultsChart
This architecture balances performance and interactivity.
The application uses PostgreSQL with Prisma ORM.
Poll
├── Options
└── Votes
Each option stores a vote counter:
votes Int @default(0)This avoids expensive aggregate queries whenever charts are rendered.
Votes are stored separately from poll options.
Benefits include:
- Historical vote tracking
- Analytics opportunities
- Future reporting features
- Better data integrity
Instead of implementing a full authentication system, PulseVote uses lightweight guest identities.
guest_a1b2c3d4e5
Each visitor receives a unique identifier stored locally.
Benefits:
- Zero onboarding friction
- Instant participation
- Persistent user identification
- Simpler architecture
Next.js App Router
│
▼
Server Components
│
▼
API Routes
│
▼
Prisma ORM
│
▼
PostgreSQL
│
▼
Server-Sent Events
│
▼
Redux Toolkit Store
│
▼
React UI
| Layer | Technology |
|---|---|
| Framework | Next.js 16 |
| Language | TypeScript |
| Styling | Tailwind CSS |
| State Management | Redux Toolkit |
| Database | PostgreSQL |
| ORM | Prisma |
| API Layer | Next.js Route Handlers |
| Real-Time Updates | Server-Sent Events (SSE) |
| HTTP Client | Axios |
| Charts | Chart.js |
| Deployment | Vercel |
app/
├── api/
│ └── polls/
│ ├── route.ts
│ └── [id]/
│ ├── route.ts
│ ├── vote/
│ ├── close/
│ └── stream/
│
├── components/
│ └── polls/
│ ├── PollCreateForm.tsx
│ ├── PollVoteClient.tsx
│ ├── PollCard.tsx
│ └── PollResultsChart.tsx
│
├── lib/
│ ├── prisma.ts
│ ├── axiosInstance.ts
│ ├── api/
│ └── utils/
│ └── guest.ts
│
├── redux/
│ ├── store.ts
│ ├── slices/
│ │ ├── pollsSlice.ts
│ │ └── votesSlice.ts
│ └── Providers.tsx
│
├── page.tsx
├── poll/
│ └── [id]/
│ └── page.tsx
└── layout.tsx
Real-time updates were required, but implementing a full WebSocket infrastructure would add unnecessary complexity.
Solution
- Server-Sent Events (SSE)
- Streaming responses
- Automatic client synchronization
- Lightweight implementation
Polls, votes, and live results must remain synchronized across multiple views.
Solution
- Redux Toolkit
- Async thunks
- Centralized state management
- Predictable state updates
Without user accounts, duplicate voting needed to be handled differently.
Solution
- Guest identifiers stored in localStorage
- Vote tracking per poll
- Client-side safeguards
Repeated aggregation queries can become expensive as poll participation grows.
Solution
- Dedicated vote counters
- Optimized Prisma queries
- Reduced database load
This project was developed using modern AI-assisted engineering workflows.
- GitHub Copilot
- Claude
- Accelerating component development
- Generating boilerplate code
- Debugging implementation issues
- Improving documentation
- Exploring architectural approaches
All final implementation decisions, architecture design, database modeling, and feature development were completed manually.
- Node.js 18+
- PostgreSQL
- npm
git clone https://github.com/Kehinde13/pulsevote.git
cd pulsevote
npm installCreate a .env file:
DATABASE_URL=your_postgresql_connection_stringnpm run devOpen:
http://localhost:3000
Generate Prisma Client:
npx prisma generateRun Migrations:
npx prisma migrate devOpen Prisma Studio:
npx prisma studio- User authentication
- Poll ownership dashboard
- Anonymous vs authenticated voting
- Poll scheduling and expiration
- Advanced analytics
- Poll templates
- Team collaboration
- Shareable insights dashboard
- Exportable poll reports
PulseVote demonstrates modern full-stack engineering principles through:
- Next.js App Router architecture
- Server and Client Component separation
- Real-time application design
- Relational database modeling
- State management with Redux Toolkit
- Data visualization
- Scalable API development
The project showcases the ability to design and build interactive, data-driven web applications using modern frontend and backend technologies.



