A full-stack ranked choice voting application with a React TypeScript frontend and Go backend deployed on AWS.
- Create polls with multiple candidates
- Cast ranked votes with drag-and-drop interface
- View real-time results with round-by-round breakdown
- Share poll links
- Anonymous voting (no authentication required)
- React with TypeScript
- Hosted on AWS Amplify
- Go (Lambda functions)
- API Gateway
- DynamoDB
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Browser │────────▶│ AWS Amplify │ │ Lambda │
│ (React) │ │ (Frontend) │ │ (Go API) │
└─────────────┘ └──────────────┘ └─────────────┘
│ │
│ │
▼ ▼
┌──────────────┐ ┌─────────────┐
│ CloudFront │ │ API Gateway │
│ CDN │ └─────────────┘
└──────────────┘ │
│
▼
┌─────────────┐
│ DynamoDB │
└─────────────┘
ranked-choice/
├── frontend/ # React TypeScript application
│ ├── src/
│ ├── public/
│ └── package.json
├── backend/ # Go Lambda backend
│ ├── cmd/lambda/ # Lambda entry point
│ ├── internal/
│ │ ├── handlers/ # API handlers
│ │ ├── models/ # Data models
│ │ └── repository/ # DynamoDB repository
│ ├── template.yaml # SAM template
│ ├── Makefile
│ └── go.mod
└── infrastructure/ # Documentation
└── dynamodb-schema.md
- Node.js 20+ and npm
- Go 1.23+
- AWS CLI configured
- AWS SAM CLI (for backend deployment)
cd frontend
npm install
npm startThe frontend will run on http://localhost:3000
cd backend
go mod download
# Build for local testing
go build -o main cmd/lambda/main.go- Install AWS SAM CLI if you haven't:
# On Windows (using Chocolatey)
choco install aws-sam-cli
# Or download from: https://aws.amazon.com/serverless/sam/- Deploy the backend:
cd backend
make deployThis will:
- Build the Go binary for Lambda
- Create a CloudFormation stack
- Deploy Lambda function, API Gateway, and DynamoDB table
- Output your API endpoint URL
- Save the API URL from the output (you'll need it for frontend configuration)
-
Push your code to GitHub/GitLab/Bitbucket
-
Go to AWS Amplify Console
-
Click "New app" → "Host web app"
-
Connect your Git repository
-
Configure build settings:
- App name:
ranked-choice-voting - Branch:
main(or your default branch) - Build settings (should auto-detect):
version: 1 frontend: phases: preBuild: commands: - cd frontend - npm ci build: commands: - npm run build artifacts: baseDirectory: frontend/build files: - '**/*' cache: paths: - frontend/node_modules/**/*
- App name:
-
Add environment variable:
- Key:
REACT_APP_API_URL - Value: Your API Gateway URL from backend deployment
- Key:
-
Click "Save and deploy"
cd frontend
# Build the app
npm run build
# Deploy to S3 (you'll need to create a bucket first)
aws s3 sync build/ s3://your-bucket-name --delete
# Configure CloudFront distribution pointing to the S3 bucketPOST /polls- Create a new pollGET /polls/{id}- Get poll detailsPOST /polls/{id}/vote- Submit a voteGET /polls/{id}/results- Get poll results
Create a Poll:
curl -X POST https://your-api-url/polls \
-H "Content-Type: application/json" \
-d '{
"title": "Best Programming Language 2024",
"description": "Vote for your favorite",
"candidates": ["JavaScript", "Python", "Go", "Rust"]
}'Submit a Vote:
curl -X POST https://your-api-url/polls/{pollId}/vote \
-H "Content-Type: application/json" \
-d '{
"rankings": ["Go", "Rust", "Python", "JavaScript"]
}'See infrastructure/dynamodb-schema.md for detailed DynamoDB schema design.
- Voters rank candidates in order of preference (1st choice, 2nd choice, etc.)
- First round: Count all first-choice votes
- If a candidate has >50% of votes, they win
- If not: Eliminate the candidate with fewest votes
- Redistribute those votes to voters' next choices
- Repeat until someone has majority
- DynamoDB: ~$0.25 per million reads/writes (on-demand)
- Lambda: Free tier includes 1M requests/month
- API Gateway: $3.50 per million requests
- Amplify Hosting: ~$0.15/GB served + $0.01/build minute
Estimated cost for small-scale usage: $1-5/month
- Frontend: Deployed on AWS Amplify
- Backend API:
https://vepv8420vl.execute-api.us-east-1.amazonaws.com/prod - Features:
- ✅ Drag-and-drop vote ranking
- ✅ Two voting methods (IRV and Borda Count)
- ✅ Real-time results with charts
- ✅ Poll sharing via URL
- ✅ Anonymous voting
MIT