Inspiration
Academic research moves fast, but almost nobody outside a lab actually reads it. Papers are locked behind dense jargon, and even a motivated student has to spend 20+ minutes just decoding a single abstract before deciding if it's worth their time. As a high school student trying to stay current in physics and math, I kept hitting this wall myself — so I built Wave to knock it down.
What it does
Wave turns real academic papers into short, natural-sounding narrated audio — like a podcast episode for a single research paper. Users browse by category (Physics, Biology, Computer Science, and more), search by title or author, and tap play to hear a clear, conversational 1-2 minute summary instead of reading a full paper. From there they can like, save, comment, download for offline listening, and build a personal library of saved and in-progress papers.
How we built it
Wave has two layers: a fully automated content pipeline and two client apps (web + mobile) sharing one backend.
Content pipeline:
- Fetch — real papers are pulled from OpenAlex, a free, open academic database, using a search term or title
- Summarize — a local LLM (Ollama, llama3.2:3b) running entirely on-device rewrites each abstract into a natural, conversational 150-220 word script meant to be heard, not read
- Narrate — edge-tts (Microsoft's free text-to-speech engine) synthesizes that script into a real mp3, using one voice and pacing tuned after testing several options
- Cover art — Pexels API supplies a unique, topically-relevant cover image per article
- Everything uploads to Supabase Storage and upserts into a Postgres articles table
Apps:
- A Vue 3 web app was built first, iterating from a TikTok-style vertical feed to a Spotify-inspired layout (sidebar, horizontal category rows, persistent bottom player) once the content proved to be audio-first, not video-first
- A native Flutter mobile app followed, built as a fully independent client against the same Supabase backend — same auth, same data, same real-time likes/comments/saves
- Supabase handles Postgres, Auth (Google OAuth), Storage, and row-level security throughout
- Figma's MCP server let me pull real design tokens and component structure directly into Claude Code while building the mobile UI
Challenges we ran into
- A full data wipe mid-build — a stray SQL script dropped every table. No backup existed on the free tier, so I rebuilt the seed pipeline and, after a long debugging session, traced a lingering "likes not saving" bug to a missing
public.usersrow that only gets created on fresh signups, not on every session — fixed with a direct REST API backfill. - Cover image repetition — early on, articles in the same category all shared near-identical stock photos because searches were too generic. Fixed by deriving Pexels search terms from each paper's actual title/topic instead of just the category name.
- Audio playback on Flutter web — hidden/automated browser tabs silently throttle
<audio>elements, which looked like a broken player until I confirmed real foregrounded playback worked correctly. - Rebuilding one Flutter build from scratch — after early iteration produced messy, hard-to-maintain code, I made the call to delete and rebuild the mobile app with a proper shared theme and component system from day one, rather than keep patching.
What's next for Wave
Scaling the article catalog well beyond the current set, wiring a "next/previous in category" real queue for the player, and submitting to the Google Play Store starting with an internal testing track.
Built With
- claude
- dart
- edge-tts
- fastapi
- figma
- flutter
- google-oauth
- llama-3.2
- ollama
- openalex-api
- pexels-api
- postgresql
- python
- supabase
- vue.js


Log in or sign up for Devpost to join the conversation.