A powerful, web-based polling and voting system that enables organizations to create, manage, and conduct secure online polls with advanced features like email notifications, participant management, and real-time results. Built with React and TypeScript, optimized for easy and fast deployment on Cloudflare Workers.
- π³οΈ Advanced Poll Management - Create, edit, and manage polls with complex ballot structures
- π₯ Participant Management - Add participants individually or import from spreadsheets with role-based access
- π§ Automated Email Notifications - Send voting invitations and reminders via SMTP with configurable limits
- π Secure Authentication - JWT-based authentication with role-based access control (Admin, Sub-Admin, User)
- π Real-time Results - View poll results with detailed analytics and vote tracking
- π― Audit Trail - Complete audit system with auditor assignments and vote verification
- π± Responsive Design - Works seamlessly on desktop and mobile devices
- π Cloudflare Workers Ready - Optimized for edge deployment with D1 database
- β° Scheduled Polls - Set start and end dates for automated poll lifecycle management
- π Cron Job Integration - Automated email sending and daily limit resets
- π Group Management - Organize users into groups for easier participant management
- π¨ Modern UI - Beautiful interface built with Tailwind CSS and React
Deploy directly to Cloudflare Workers with one click:
[Deploy to Cloudflare Workers]
- Clone the repository
git clone https://github.com/yourusername/voter98.git
cd voter98- Install dependencies
# Install backend dependencies
cd backend
npm install
# Install frontend dependencies
cd ../frontend
npm install- Set up environment variables
Create a.envfile in the backend directory:
JWT_SECRET=your-secret-key
FRONTEND_URL=http://localhost:5173- Set up database
cd backend
npm run db:generate
npm run db:migrate:local- Start development servers
# Start backend (in backend directory)
npm run dev
# Start frontend (in frontend directory)
npm run dev- Open in browser
Frontend: http://localhost:5173
Backend API: http://localhost:8787
- Frontend: Vite, React 19, TypeScript, Tailwind CSS, Cloudflare Workers
- Backend: Hono.js, TypeScript, Drizzle ORM, Cloudflare Workers
- Database: Cloudflare D1 (SQLite)
- Authentication: JWT with bcrypt
- Email: SMTP integration with worker-mailer
- Register/login with email and password
- Role-based access: Admin, Sub-Admin, User
- JWT-based session management
- Navigate to Dashboard and click "Create New Poll"
- Set poll title, description, and schedule
- Configure ballot questions (multiple choice, text, etc.)
- Set up email notifications if needed
- Add participants individually or import from CSV
- Assign participants to groups for easier management
- Set vote weights for weighted voting
- Generate unique tokens for non-user participants
- Set up SMTP configuration in Admin Panel
- Configure daily email limits and cron job limits
- Customize email templates and content
- Draft: Poll is being created and configured
- Active: Poll is open for voting
- Completed: Poll has ended, results available
- Cancelled: Poll was cancelled
- Participants receive email invitations with unique links
- Secure token-based voting for non-users
- Real-time vote tracking and validation
- Audit trail for all voting activities
- View real-time poll results
- Export results in various formats
- Detailed analytics and vote breakdowns
- Auditor verification system
- Corporate Voting - Board elections, policy decisions, and shareholder votes
- Academic Elections - Student council elections, faculty voting, and course evaluations
- Community Polls - Neighborhood decisions, community surveys, and local elections
- Event Planning - Conference session voting, meetup topics, and event preferences
- Product Development - Feature prioritization, user feedback, and roadmap decisions
- Non-profit Governance - Board member elections, policy changes, and member votes
- Research Surveys - Academic research, market surveys, and data collection
- Internal Communications - Employee satisfaction surveys, team decisions, and feedback collection
- from Cloudflare dashboard, Workers, voter98-backend, Bindings,
Add Binding, chooseD1 databaseand press Add, Variable name isDB, D1 database isvoter-dbwhich you'll create here - again
Add Binding, chooseKV namespaceand press Add, Variable name isVOTER_KV, KV namespace isvoter-kvwhich you'll create here - navigate to
Settings, Variables and Secrets,Add, Text, Variable name isFRONTEND_URL, Value ishttps://voter98-frontend.your-username.workers.dev
- Cloudflare account
- Node.js 18+ installed
- Git repository cloned
npm install -g wrangler
wrangler login# Create D1 database
wrangler d1 create voter-db
# Create KV namespace (optional, for caching)
wrangler kv:namespace create VOTER_KV
wrangler kv:namespace create VOTER_KV --preview- Copy configuration template:
cd backend
cp wrangler.jsonc.template wrangler.jsonc- Update
wrangler.jsoncwith your values:
{
// ...
"vars": {
"JWT_SECRET": "your-super-secret-jwt-key-change-this-in-production",
"FRONTEND_URL": "https://your-frontend-url.workers.dev"
},
"kv_namespaces": [
{
"binding": "VOTER_KV",
"id": "YOUR_KV_NAMESPACE_ID_HERE",
"preview_id": "YOUR_KV_PREVIEW_NAMESPACE_ID_HERE"
}
],
"d1_databases": [
{
"binding": "DB",
"database_name": "voter-db",
"database_id": "YOUR_D1_DATABASE_ID_HERE"
}
]
}- Deploy backend:
npm run deploy- Note your backend URL (e.g.,
https://voter15-backend.your-username.workers.dev)
- Create environment file:
cd ../frontend- Create
.envfile:
VITE_API_BASE_URL=https://voter15-backend.your-username.workers.dev/api- Build and deploy frontend:
npm run build
npm run deploy- Note your frontend URL (e.g.,
https://voter15-frontend.your-username.workers.dev)
- Update backend
wrangler.jsoncwith your frontend URL:
{
"vars": {
"JWT_SECRET": "your-super-secret-jwt-key-change-this-in-production",
"FRONTEND_URL": "https://your-frontend-url.workers.dev"
}
}- Redeploy backend:
cd ../backend
npm run deploy- Apply database migrations:
npm run db:migrate:remote- Seed the database (only in development):
# Make a POST request to seed endpoint
curl -X POST https://your-backend-url.workers.dev/api/dev/seedDefault seed user:
- Admin:
admin@example.com/password123
- Access your application at your frontend URL
- Login as admin using the seed credentials
- Navigate to Admin Panel β SMTP Settings
- Configure your SMTP settings:
- SMTP Host (e.g.,
smtp.gmail.com) - Port (e.g.,
587for TLS) - Username and Password
- Daily email limits
- Cron job limits
- SMTP Host (e.g.,
- Visit your frontend URL
- Login with seed credentials
- Create a test poll
- Test email functionality (if SMTP is configured)
{
"vars": {
"JWT_SECRET": "your-jwt-secret-key",
"FRONTEND_URL": "https://your-frontend-url.workers.dev"
}
}VITE_API_BASE_URL=https://your-backend-url.workers.dev/api- CORS Errors: Ensure
FRONTEND_URLin backend config matches your frontend URL exactly - Database Connection: Verify D1 database ID is correct in
wrangler.jsonc - Email Not Working: Check SMTP configuration in Admin Panel
- Build Errors: Ensure all dependencies are installed with
npm install
- Development: Use
npm run db:migrate:localfor local database - Production: Use
npm run db:migrate:remotefor production database - Seeding: Only available in development (JWT_SECRET contains "development")
The built application can be deployed to any static hosting service:
- Netlify: Drag and drop the
distfolder - Vercel: Connect your repository for automatic deployments
- GitHub Pages: Use the built files from
dist/
npm run dev- Start development servernpm run deploy- Deploy to Cloudflare Workersnpm run db:generate- Generate database migrationsnpm run db:migrate:local- Apply migrations locallynpm run db:migrate:remote- Apply migrations to productionnpm run db:studio- Open Drizzle Studio
npm run dev- Start development servernpm run build- Build for productionnpm run preview- Preview production build locallynpm run deploy- Deploy to Cloudflare Workers
The application uses the following main entities:
- Users - Authentication and user management
- User Groups - Organization of users into groups
- Polls - Poll configuration and metadata
- Poll Participants - Voting participants with tokens
- Poll Votes - Individual vote records
- Poll Auditors - Audit trail management
- SMTP Config - Email configuration settings
JWT_SECRET- Secret key for JWT token generationFRONTEND_URL- Frontend application URLDB- D1 database binding (Cloudflare Workers)VOTER_KV- KV namespace for caching (optional)
Configure email settings through the Admin Panel:
- SMTP host and port
- Authentication credentials
- Daily email limits
- Cron job execution limits
We welcome contributions! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
- Follow TypeScript best practices
- Use Tailwind CSS for styling
- Write meaningful commit messages
- Test your changes thoroughly
- Update documentation as needed
-
Enhanced Security
- Two-factor authentication
- IP-based voting restrictions
- Advanced audit logging
- Blockchain integration for vote verification
-
Advanced Polling Features
- Ranked choice voting
- Approval voting
- Multi-stage polls
- Poll templates and cloning
-
Email Integration
- Advanced email templates
- Email tracking and analytics
- Bulk email management
- Email campaign scheduling
-
Analytics & Reporting
- Advanced analytics dashboard
- Export to multiple formats
- Real-time charts and graphs
- Custom report generation
-
User Experience
- Dark mode support
- Multi-language support
- Mobile app development
- Offline voting capabilities
-
Integration Features
- API for third-party integrations
- Webhook support
- SSO integration
- Calendar integration
Found a bug or have a feature request? Please create an issue on GitHub Issues.
This project is licensed under the AGPLv3 License - see the LICENSE file for details.
- Built with React and TypeScript
- Styled with Tailwind CSS
- Deployed on Cloudflare Workers
- Database powered by Cloudflare D1
- Email functionality by worker-mailer
- Authentication with JWT and bcrypt
Made with β€οΈ by the 98tools Team
β Star this project β’ π Report Bug β’ π§ Request Feature