Most polling tools do one thing: a question, a handful of options, one vote each. That covers a small slice of the decisions people actually make together. Finding a date that works for eight people is not the same problem as picking a name, and ranking a backlog is not the same problem as choosing a restaurant.
FlexPoll is my attempt at one tool that handles all of them. It is free, open source under the MIT licence, and voting never requires an account — you send a link, people answer, that is the whole flow.
Seven ways to ask
- Standard — classic multiple choice, optionally allowing more than one selection.
- Schedule — propose dates and time slots and let everyone tick what works. The overlap does the deciding.
- Location — suggest venues on a map and vote on where to meet.
- Ranking — drag options into order. Results are aggregated with Borda count, so a strong second place still counts for something.
- Priority — each voter gets a budget of points to spread across the options. Good for roadmaps, where “everything is important” is not an answer.
- Image — upload pictures as the options and vote on the one you like.
- Custom — build the poll body yourself in a rich-text editor when none of the above fits.
Beyond the vote
Results stream in live over Firestore subscriptions, so an open results page updates as votes arrive rather than on refresh. Every poll gets a share link, a generated QR code and a WhatsApp share action — the three ways people actually distribute a poll. Polls can be marked private so they stay out of the public Explore feed and are reachable only by direct link, and they close automatically once their duration runs out.
There is a contacts list for people you poll often, and optional notifications: invited contacts can be notified by email when a poll opens, and web push runs through Firebase Cloud Messaging with a Cloud Function draining a queue collection.
How it is built
The front end is React 19 with TypeScript, built by Vite and styled with Tailwind. Routing is React Router v7, and the app ships as an installable PWA with a dark mode. Firebase handles the backend: Authentication for accounts, Firestore for polls and votes, and Cloud Functions for push. Vote casting runs inside Firestore transactions so concurrent votes cannot clobber each other’s counts, and security rules — not the UI — decide who may write what.
The result is a project with no server to operate and no running cost, which is what makes “free forever” a promise I can actually keep.