Lessons from VoteWise AI on Building Election Guides with Next.js and Gemini 2.5 Flash
Contents
A VoteWise AI implementation article showed up on DEV Community.
The original is “How I Built VoteWise AI: Gamifying Democracy with Next.js & Gemini 2.5 Flash,” published May 2, 2026 at 10:36:48 UTC.
It covers moving election education away from government PDFs and long FAQs toward a mobile-first AI chat with a story mode.
VoteWise AI supports 13 countries, 16 languages, voice I/O, an election calendar, and kid-friendly analogy generation. The stack is Next.js 15 App Router, React, Tailwind CSS, Framer Motion, Zustand, Firebase Anonymous Auth, Firestore, Gemini API, and Cloud Run.
This kind of civic tech is thin if it just slaps an AI chatbot on top.
What makes it interesting is that it brings low-latency models, voice, and gamified explanations together for a domain that is both politically sensitive and genuinely intimidating for new voters.
From Static Info Pages to Conversational Guidance
The problem VoteWise AI targets is not candidate recommendation but the friction at the entrance: “I don’t understand the system, so I don’t participate.”
It lets users ask about voting procedures, registration, electoral systems, terminology, and cross-country differences.
What changes here is not the amount of information but the path to it.
Traditional election-info sites tend to assume users already know the right page name or the right term. A chat UI lets people start with vague questions like “what is the Electoral College” or “what do I need to check next.”
That said, VoteWise AI is not a voting system that handles actual ballots.
In an earlier piece on voting-right design patterns, I looked at how to design authentication, serial codes, and duplication prevention for real voting systems. VoteWise AI sits a layer before all that, reducing confusion and anxiety before participation rather than handling ballot issuance or tallying.
If you were to add mock-voting or school-election features to this app, that’s a different problem entirely.
Authentication, double-vote prevention, logging, anomaly detection, and rate limiting would take center stage over AI chat quality.
The Tension of Using Gemini 2.5 Flash for Elections
Gemini 2.5 Flash is positioned as the price-performance and low-latency model on Google’s official model page.
It accepts text, image, video, and audio input and outputs text. The input cap is 1,048,576 tokens, output cap is 65,536 tokens, and it supports structured output, function calling, search grounding, URL context, and thinking.
For a use case like VoteWise AI, this “fast and smart enough” profile fits.
Explaining electoral terms, generating stories, handling multilingual responses, and providing calendar-based guidance are all tasks where stable low-latency responses matter more than deep reasoning on every turn.
On the other hand, elections are treated specially in Gemini API’s safety filters.
The official safety-settings documentation includes HARM_CATEGORY_CIVIC_INTEGRITY, described as covering election-related queries. The adjustable categories list harassment, hate, sexual content, dangerous content, and civic integrity side by side.
Having this category is reasonable, but it has practical design implications.
Whether a user asks “who should I vote for,” “what is proportional representation,” or “what do I need to register in this country” calls for very different response handling.
graph TD
A[User question] --> B[Detect country and language]
B --> C[Classify: explanation or recommendation?]
C --> D[Explanation: answer with sources]
C --> E[Recommendation: redirect to neutral guidance]
D --> F[Present via voice and screen]
E --> F
As I touched on in a piece on LLM safety filters, cloud LLM blocking is not determined by the model alone. Input filters, system prompts, trained refusal tendencies, and output filters all stack up.
For an election guide AI, it’s better to design on the app side which questions to refuse and which to convert into explanations, rather than relying solely on model-level safety.
Story Mode as a Translation Layer for Electoral Jargon
The most app-like feature in the original article is Story Mode.
It explains concepts like the Electoral College and parliamentary democracy through kid-friendly analogies and AI-generated illustrations.
It looks like gamification, but what it actually does is translate institutional jargon into everyday language.
For example, explaining “Electoral College” verbatim stops most people at the first word. A pizza-topping or class-representative analogy sacrifices some precision but reaches first-time understanding.
The problem is that overly strong analogies flatten the differences between systems.
Electoral systems across countries vary between proportional representation, single-member districts, two-round voting, electoral colleges, parliamentary systems, and presidential systems. If Story Mode is used seriously, a short correction of “here’s how the real system differs” after each analogy is essential.
| Layer | Role | Failure mode |
|---|---|---|
| Chat | Widens the entry point for questions | Can drift toward recommendation or steering |
| Story | Turns complex systems into analogies | Analogies can erase system differences |
| Voice | Reduces reading burden | Long responses cause listener fatigue |
| Calendar | Connects to next action | Date or regional errors become critical |
| Firestore | Maintains state and history | Weak rules create privacy risks |
API Route and Cloud Run Architecture Are Solid
The most concrete part of the original article is keeping the Gemini API key off the client by using a Next.js API Route at /api/chat as a relay.
On top of that, input sanitization, prompt injection defenses, and an in-memory rate limit of 20 requests per minute per IP are mentioned.
This setup is sound.
However, if you scale to multiple instances on Cloud Run, in-memory rate limiting splits across instances. It works for hackathons and small demos, but if you want to keep abuse costs down in production, moving to Redis, Firestore, or Cloud Armor is the call.
For the Cloud Run deployment, the article mentions using Next.js’s output: 'standalone'.
Google Cloud’s quickstart for Next.js on Cloud Run provides a ready path. Since Secret Manager is accessible from Cloud Build too, separating Firebase’s public config from secrets like the Gemini API key is a natural choice.
graph TD
A[Next.js UI] --> B[API Route]
B --> C[Input classification and rate limiting]
C --> D[Gemini API]
B --> E[Firestore]
B --> F[Secret Manager]
A --> G[Web Speech API / TTS]
The voice layer overlaps with territory covered in a survey of voice APIs for AI conversation.
VoteWise AI seems to add speech recognition and text-to-speech on top of a screen-based chat experience, rather than plugging into a real-time voice conversation model directly. For low-cost multilingual coverage, that’s the easier path.
What Hasn’t Been Validated Yet
The original is a three-minute build log, not a validation report.
The live demo returns HTTP 200 and the GitHub repo is public.
But model answer accuracy, per-country data update procedures, citation of election-information sources, load testing, and abuse testing are not shown.
Viewed as an election guide AI, the next items to nail down are:
- Can answers always cite institutional sources?
- Can users see when country/region/language data was last updated?
- How are candidate recommendations, party comparisons, and vote steering handled?
- Where is the line between explanation and personal-data collection?
- Can voice-input misrecognition lead to politically dangerous responses?
“Gamifying democracy with AI” is a flashy pitch.
But the implementation is really about decomposing electoral education into conversation, voice, and analogy, and that part is genuinely useful. If it stays away from candidate recommendation and focuses on reducing pre-participation confusion, the Gemini 2.5 Flash and Next.js combo is quite practical.
Japan’s Electoral System as a Test Case
VoteWise AI claims to cover 13 countries, but whether Japan is among them is unclear.
Japan’s electoral system is a good example of high difficulty for “explaining systems through analogies,” so it’s worth walking through.
Japan’s national elections use a bicameral system with the House of Representatives (Shugiin) and the House of Councillors (Sangiin).
Each chamber has a different election mechanism.
The House of Representatives’ Parallel System
The House of Representatives has 465 seats, elected through two parallel tracks.
Single-member districts (SMDs) account for 289 seats.
The country is divided into 289 districts, each electing one winner by plurality.
Proportional representation (PR) accounts for 176 seats.
The country is split into 11 regional blocks, and seats are distributed to parties based on vote share. The list order is fixed by each party in advance (closed-list PR).
The fact that these two tracks are calculated independently is the defining feature of Japan’s “parallel system.”
Germany and New Zealand use a “mixed-member proportional” (MMP) system where PR seats compensate for distortions in the SMD results. Japan’s parallel system has no such compensation, so a party that wins big in SMDs also takes a proportional share of PR seats.
On top of this, Japan allows dual candidacy.
A candidate can run in both an SMD and the PR list simultaneously. If they lose the SMD race, they may still win a PR seat based on their list ranking and “close-loss ratio.”
The close-loss ratio (sekihairitsu) is calculated as “the candidate’s vote count / the SMD winner’s vote count.”
Among candidates tied at the same list position, those with a higher close-loss ratio get seats first.
The House of Councillors’ Constituency and Nationwide PR
The House of Councillors has 248 seats, with half (124) up for election every three years.
Constituency seats total 148 (74 per election). These are allocated by prefecture, with each prefecture getting 1 to 6 seats.
PR seats total 100 (50 per election). This is nationwide open-list PR, where voters can write either a party name or an individual candidate’s name. Candidates with more individual-name votes win first.
In 2019, “priority allocation slots” (tokutei-waku) were introduced.
Candidates designated for these slots are fixed at the top of the list regardless of individual votes. This effectively lets parties assign PR seats by fiat despite the open-list structure, and it was controversial when introduced.
How the D’Hondt Method Allocates Seats
I wrote “seats are distributed based on vote share” above, but the actual algorithm is the D’Hondt method.
Both the House of Representatives’ PR and the House of Councillors’ PR in Japan use D’Hondt to determine each party’s seat count.
The procedure is straightforward: divide each party’s total votes by 1, 2, 3, 4, etc., and assign seats in order of the largest quotients.
Here’s a hypothetical block with 5 seats where Party A got 1,200 votes, Party B 720, and Party C 300:
| Divisor | Party A (1,200) | Party B (720) | Party C (300) |
|---|---|---|---|
| /1 | 1,200 (1) | 720 (2) | 300 |
| /2 | 600 (3) | 360 (5) | 150 |
| /3 | 400 (4) | 240 | 100 |
| /4 | 300 | 180 | 75 |
Sorting quotients largest-first gives 1,200, 720, 600, 400, 360, so the first 5 seats go to Party A (3), Party B (2), Party C (0).
By vote share, Party A has 54%, Party B 32%, Party C 14%, so strict proportional allocation for 5 seats would be A 2.7, B 1.6, C 0.7. D’Hondt tilts slightly toward larger parties.
This “slight tilt” compounds, and small parties can end up with zero seats in some blocks.
Japan’s House of Representatives PR is split into 11 blocks, with the smallest (Shikoku) having only 6 seats. The fewer the seats, the stronger D’Hondt’s large-party bias, so small parties can only win seats in large blocks like Kinki or South Kanto.
Other methods exist: the Sainte-Laguë method (divisors 1, 3, 5, 7…) favors mid-to-small parties and is used in Nordic countries. The Hare-Niemeyer method (largest remainder) was used in the German Bundestag for a period. Japan sticks with D’Hondt across the board, structurally favoring large parties.
If VoteWise AI’s Story Mode tried to explain D’Hondt, a “dividing a pizza” analogy wouldn’t cut it.
It’s a procedural algorithm of filling a division table, so an interactive simulation would work better than an analogy. Show a UI where users enter vote counts and watch the allocation shift, and it’ll click faster than any verbal explanation.
The Difficulty of Conveying Japan’s System in Story Mode
Trying to convey this system in VoteWise AI’s Story Mode reveals the hard parts.
The “parallel” nature of SMDs and PR defies pizza analogies.
The sheer fact that voters receive two different ballots in the same election is unfamiliar to voters in most countries. Dual candidacy and the close-loss ratio are things even Japanese voters who know the system struggle to explain accurately.
| System element | Difficulty | Story Mode challenge |
|---|---|---|
| Bicameral legislature | Low | Exists in many countries, easy to analogize |
| Single-member districts | Low | Similar to UK/US systems |
| Proportional representation | Medium | Need analogies that don’t flatten closed vs. open list |
| D’Hondt method | High | Procedural division table; better suited to simulation |
| Parallel system | High | Need to accurately convey the difference from MMP |
| Dual candidacy | High | Almost no other country has this |
| Close-loss ratio | Very high | Turning the calculation into an analogy invites misunderstanding |
| Priority allocation slots | High | An exception within the system, i.e. a system within a system |
If VoteWise AI supports Japan, Story Mode analogies alone won’t do.
Either show “how the real system works” immediately after each analogy, or let users ask questions in chat to get progressively finer explanations matched to their level.
That said, re-reading all of this, “so who actually uses this thing” still bugs me.
Basic questions about electoral systems get decent answers from general-purpose LLMs, and neither the motivation to maintain election data for 13 countries as an individual nor a mechanism to ensure answer accuracy came through in the original article.
”Gamification” is the banner, but it’s really just Story Mode. There’s no game-like incentive design.
Established civic-tech players like Vote.org and Ballotpedia have verified, structured data they maintain themselves.
Their credibility rests on accurate data, not LLM output.
VoteWise AI has no such data layer and relies on Gemini’s general knowledge. At that point, you might as well ask a general LLM directly without a dedicated app in between.
It’s well put together as a portfolio piece.
But if you’re going to call it an “election guide AI,” the story of what data foundation and verification process sits on top of the LLM wrapper needs to be visible. Otherwise the branding is outrunning the substance.
Thinking a bit further, general electoral-system explanations are something general-purpose LLMs already handle fine.
Where VoteWise AI might actually fit is in guiding users through voting flows specific to a particular event or app, the kind of thing that isn’t in a general LLM’s training data.
For example, the Hypnosis Mic theatrical film had a system where audiences voted in real time during screenings.
In-app voting, vote timing, and web-based result checking all ran in parallel, making it quite hectic for first-timers.
If an in-app AI could instantly answer “how does voting work in this specific event,” there’s a clear use case.
Then again, you could also solve that with a well-designed tutorial UI.
Whether there’s a gap between “the system is complex so let people ask an AI” and “guide people step by step through UI” that only AI can fill, I honestly still don’t know.