A group-ideation tool for hackathons that collects every teammate's idea privately, then fuses them. Each person submits one pitch without seeing anyone else's β openly or anonymously, their choice β and when the last one lands, AI takes the single most distinctive element out of every submission and builds four new project ideas that each carry a piece of everybody's thinking. Then the team votes, and turns the winner into a build plan.
βΆ Live: hivemind.rianfernando.com Β· Guided demo Β· Architecture Β· Privacy model
Group brainstorms are decided by whoever speaks first and loudest. Every quiet person's idea evaporates, and the team converges on the first plausible thing said out loud. HiveMind removes the ordering problem entirely: pitches are collected in parallel and in private, and fusion is mechanical β every participant's idea is required to appear in every generated concept. The results show which element came from whom, so nobody has to argue that they contributed.
The part that makes people actually use it is the privacy toggle. Each person independently decides whether their name and their pitch text are public. A fully anonymous pitch still shapes all four results β it just never appears in the credits. That is enforced on the server, not in the UI: the browser has no read access to pitches at all, and the AI is handed placeholder labels instead of hidden participants' names.
And it deliberately stops short of deciding for you. The AI produces raw material; the team argues, votes, and commits. Nothing auto-advances past the reveal.
flowchart LR
subgraph Clients["Participants Β· phones and laptops"]
H["Host<br/>creates room"]
P["Pitchers<br/>one idea each"]
end
subgraph App["Next.js 15 Β· Vercel"]
API["API routes<br/>service-role only"]
MASK["Privacy masking"]
end
subgraph Data["Supabase"]
DB[("Postgres<br/>rooms Β· ideas Β· votes")]
RT["Realtime<br/>rooms row only"]
end
subgraph AI["AI Β· free tiers"]
GEM["Gemini<br/>primary"]
GRQ["Groq Β· Llama 3.3<br/>fallback"]
end
H --> API
P --> API
API -->|writes| DB
DB --> RT
RT -->|"content-free ping"| Clients
Clients -->|"masked view"| MASK
API -->|"placeholder labels"| GEM
GEM -.->|"rate limit / bad JSON"| GRQ
GEM --> MASK
GRQ --> MASK
MASK -->|"credits per privacy choice"| DB
The browser can read exactly one table (rooms, which holds nothing sensitive)
and write nothing. Every mutation goes through an API route holding the
service-role key. Realtime publishes only the rooms row, so pitch text is
never broadcast β writes bump updated_at as a content-free "something changed"
ping and clients refetch a masked view. Full detail in
docs/architecture.md.
- Rooms in one step β name the event, set the group size (2β50), optionally set a pitch countdown. Share a link, a QR code, or a six-letter code.
- Private pitching β one idea per person, submitted without seeing the others. Two independent toggles hide your name, your idea text, or both.
- Live room β visible pitches stream in with π₯π‘π reactions and a progress bar; a countdown, when set, fires fusion automatically at zero.
- Fusion β one AI call per room extracts the most distinctive element of each pitch and combines them into four hackathon-scoped concepts, credited according to each person's privacy choice.
- Voting β one changeable vote per device, live tallies, leading idea crowned.
- Build plans β per idea, on demand: MVP features, a stack with reasoning, a role for each teammate, stretch goals, and a first-hour checklist. Cached room-wide, so only the first click pays for it.
- Presenter view β
/room/CODE/presentfor a projector: a large QR code and live counter, then oversized result cards with live tallies. - Export β copy or download the whole session as Markdown, votes and build plans included.
| Hide name | Hide idea | In the live room | In the results |
|---|---|---|---|
| β | β | Maya β food-waste mapβ¦ |
Maya Β· real-time maps |
| β | β | Anonymous β food-waste mapβ¦ |
Anonymous Β· real-time maps |
| β | β | Maya β π pitch kept private |
Maya Β· secret ingredient π€« |
| β | β | Anonymous β π pitch kept private |
no credit at all |
Enforced at four points: no browser read access to the ideas table, a masking
route for every read, placeholder labels in the AI prompt, and masking of the
AI's output before it is stored anywhere browser-readable. The limits of the
model are written down honestly in
docs/privacy-model.md β including the fact that small
rooms leak by arithmetic and that the operator can always read raw pitches.
| Layer | Choice | Free tier |
|---|---|---|
| Frontend + API | Next.js 15 (App Router), React 19 on Vercel | Hobby, free |
| Database + realtime | Supabase Postgres | 500 MB, Realtime included |
| AI β primary | Google Gemini | free API tier, no card |
| AI β fallback | Groq (Llama 3.3 70B) | free API tier, no card |
| 3D landing | three.js + React Three Fiber | open source, renders on-device |
| QR codes | qrcode.react |
generated client-side, no service |
| Feedback | Feedex | one script tag, optional |
Nothing here bills. Fusion runs once per room and a build plan once per idea, so
a busy event costs a handful of AI calls rather than one per person. Attribution
for every third-party service is in NOTICE.md.
Two free accounts (Supabase, plus Google AI Studio and/or Groq for keys), about ten minutes.
git clone https://github.com/Rian-Fernando/HiveMind.git
cd HiveMind
npm install
cp .env.example .env.local # fill in the five values
npm run dev1 β Supabase. Create a free project, open SQL Editor β New query, paste
supabase/schema.sql and run it. Copy the project URL,
the anon key and the service_role key from Project Settings β API.
(Upgrading an older deployment? Run
supabase/migration-002-features.sql
instead.)
2 β AI keys. aistudio.google.com/apikey for Gemini, console.groq.com/keys for Groq. Either one alone works; with both, Groq covers Gemini's rate limit.
3 β Run. npm run dev, then open the room link in a second browser or an
incognito window to play a teammate.
Deploy: import the repo at vercel.com/new, add the
same five environment variables, deploy. Set your custom domain as the primary
so the canonical URL and the *.vercel.app redirect line up.
Feedback (optional). Setting NEXT_PUBLIC_FEEDEX_KEY to a project key from
Feedex puts a feedback button on every page
except the presenter view, with browser and page context attached to each
report. Leave it unset β the default β and nothing is rendered or requested.
npm run dev # local dev server
npm run build # production build
npm run typecheck # tsc --noEmit β same check CI runsapp/
page.tsx landing β server-rendered story + FAQ, 3D backdrop
demo/page.tsx guided walkthrough on sample data
llms.txt/route.ts machine-readable summary for AI answer engines
room/[code]/page.tsx the room: pitch + privacy, countdown, live feed
room/[code]/present/ presenter view for projectors
api/rooms/route.ts POST β create room (code + hashed host key)
api/ideas/route.ts POST β submit an idea (validation + privacy flags)
api/progress/route.ts GET β privacy-masked pitches + reaction tallies
api/reactions/route.ts POST β toggle π₯π‘π on a visible pitch
api/votes/route.ts GET/POST β live tallies, one vote per device
api/generate/route.ts POST β race-safe fusion, Gemini β Groq, masked
api/deepdive/route.ts POST β build plan per idea, cached room-wide
components/
ResultsView.tsx results, voting, build-plan modal, export, confetti
CreateRoomPanel.tsx the landing page's one interactive island
DemoWalkthrough.tsx the demo stages
three/HiveScene.tsx the scroll-driven WebGL scene
three/HiveBackdrop.tsx mounts it β WebGL, reduced-motion and perf guards
lib/
ai.ts prompts, both providers, fallback
device.ts anonymous device key + room history
supabaseAdmin.ts service-role client (API routes only)
supabaseBrowser.ts anon client (reads rooms only)
supabase/
schema.sql full schema for a fresh project
migration-002-features.sql upgrade path for earlier deployments
docs/
architecture.md trust boundaries, exactly-once generation, AI layer
privacy-model.md the four modes, enforcement points, and the limits
The landing page is fully server-rendered semantic HTML β the 3D scene is a
decorative, aria-hidden canvas behind it, dynamically imported so first load
stays around 110 kB. Search engines and AI answer engines read real content, not
an empty shell.
sitemap.xml,robots.txt, canonical URLs, and a permanent redirect from the raw*.vercel.apphost/llms.txtfollowing the llms.txt convention, advertised in<head>- Fourteen AI crawlers allowed by name β GPTBot, OAI-SearchBot, ClaudeBot, PerplexityBot, Google-Extended, Applebot-Extended, CCBot and others
SoftwareApplication,FAQPageandHowTostructured data- One
<h1>per page, real landmarks, a 1200Γ630 PNG social image, andprefers-reduced-motionhonoured across both CSS and WebGL
MIT β see LICENSE. Third-party attribution in
NOTICE.md; release history in CHANGELOG.md.
Built by Rian Fernando.



