Introducing Fluora

7 min read
Next.jsLanguage LearningSpaced RepetitionOpen Source

Most language apps are designed to be addictive. Streaks, gems, leaderboards, hearts, notification guilt. The mechanics are borrowed from mobile games, and the result is an experience optimized for daily opens, not actual acquisition. You can maintain a 365-day streak and still not be able to read a newspaper.

I wanted something different. I built Fluora — a language learning app that teaches Danish and Japanese vocabulary through frequency-ranked sentences, spaced repetition, and an interface that gets out of your way.

The Core Idea

Language acquisition research has established two things that most apps ignore.

First, word frequency matters enormously. The most common 2,000 words in any language cover roughly 90% of everyday text. Learn those first, and you can read most things with reasonable comprehension. Learn them out of order, and you spend months on vocabulary you'll rarely encounter.

Second, words learned in context stick. Isolated flashcards (apple → æble) build recognition but not fluency. Words encountered in real sentences — with grammar, word order, and meaning surrounding them — build the neural pathways that actual reading and listening require.

Fluora combines both. It teaches vocabulary through frequency-ranked word lists, presented in contextual sentences, reviewed at spaced intervals tuned to your recall accuracy. You learn the most useful words first, in real sentences, at the pace your memory actually retains them.

How It Works

The learning loop is simple and deliberate.

You're presented with a sentence in your target language. One word is missing. You type it. Fluora tells you immediately whether you got it right, shows the full sentence, and plays native audio so you hear the correct pronunciation. Then the spaced repetition algorithm schedules your next review — sooner if you struggled, later if it was easy.

Two modes serve different skills. Reading mode shows you the sentence and asks you to supply the missing word from context. Listening mode plays the audio first — you have to parse the spoken sentence and produce the word from sound alone. Same exercise, different input channel, dramatically different cognitive demand.

Each session adapts to how much time you have. Quick sessions surface your most overdue reviews. Normal sessions mix reviews with new material. Extended sessions push deeper into fresh vocabulary. You choose the length, Fluora fills it with the right content.

Content at Scale

Fluora ships with approximately 14,000 sentences across Danish and Japanese, organized into 14 stories (7 per language) spanning two difficulty levels. Each story contains hundreds of sentences with vocabulary carefully mapped to frequency bands.

Every sentence includes:

  • Native audio generated via Edge-TTS
  • Morphological token data — part-of-speech tags, IPA transcriptions for Danish, furigana readings for Japanese
  • Frequency rankings drawn from 2,000-word lists per language
  • Contextual translations and word-level glosses

The content pipeline generates structured JSON from source material, processes it through linguistic annotation, synthesizes audio for every sentence, and outputs seed-ready data. The result is 222 audio files and a rich dataset that Prisma seeds into SQLite on first run.

Design Philosophy

Fluora's interface is built on a principle: calm over loud.

The accent color is sage green — a single, muted tone drawn from the botanical theme of the name (flora + fluency). There are no competing colors, no red-amber-green traffic lights for performance, no confetti animations for correct answers. Visual hierarchy comes from typography, spacing, and opacity, not from a rainbow of status indicators.

The layout is a single column, max-width 600px. Generous whitespace. No sidebar, no persistent navigation drawer, no floating action buttons. The screen shows exactly what you need for the current task and nothing else.

There is no gamification. No streaks. No gems. No leaderboards. No hearts that punish mistakes. The only metric that matters is whether you're learning, and Fluora tracks that through accuracy rates and review intervals, not through social pressure or loss aversion.

Dark mode ships as a first-class feature, not an afterthought. Every color token is defined for both light and dark contexts, and the warm neutral palette — not pure black, not pure white — reduces eye strain during long study sessions.

The Tech Stack

Fluora is built on Next.js 15 with React 19, TypeScript in strict mode, and Tailwind CSS v4 using the CSS-first @theme configuration in globals.css — no tailwind.config file.

Data lives in SQLite via Prisma 6. For a single-user local application, SQLite is the right choice: zero configuration, no external process, fast reads, and the entire database is a single file you can back up by copying it. Content is seeded from structured JSON files in the data/ directory.

Client state is split between two tools. Zustand manages ephemeral UI state — the practice player, user settings, session progress. TanStack Query handles server data — vocabulary lists, story content, review schedules — with caching, background refetching, and optimistic updates.

Audio is pre-generated and served as static files from public/audio/{lang}/{slug}/. No runtime synthesis, no API calls during practice. The audio is there when you need it, instantly.

The design system enforces a strict token-based approach. Every color, every spacing value, every typographic choice maps to a CSS custom property. Components never use raw Tailwind color scales — only Fluora's design tokens. This guarantees visual consistency across every screen and makes theming (including dark mode) a matter of swapping variable values, not rewriting styles.

What's in the MVP

The initial release covers the complete learning workflow:

Dashboard — Your home screen. Daily goal tracking, current streak (displayed quietly, not gamified), quick access to practice sessions, and an overview of your progress across languages.

Practice Sessions — The core experience. Choose quick, normal, or extended sessions. Reading and listening modes. Immediate feedback with audio playback. Spaced repetition scheduling happens automatically after each response.

Vocabulary Management — Browse your entire word list. Filter by language, frequency band, mastery level. See every word's history: when you learned it, how often you've reviewed it, your accuracy rate. Eight frequency bands per language, with a 70% mastery threshold to unlock the next level.

Insights — Activity heatmaps showing your study patterns over time. Accuracy tracking across languages and difficulty levels. Progress visualization that shows genuine learning curves, not engagement metrics.

Settings — Language preferences, session defaults, audio configuration, display options, dark mode toggle.

What's Next

Fluora currently teaches Danish and Japanese. The content pipeline is language-agnostic — adding a new language requires frequency lists, source sentences, and audio generation, not code changes. More languages are the natural next step.

Mobile is on the roadmap. The current responsive design works on phones, but a dedicated mobile experience with offline support and background audio would make Fluora a true daily companion.

Longer term, there's room for community features — shared word lists, user-contributed sentences, collaborative story creation — though any social layer will follow the same design principle: it should support learning, not gamify it.

The Name

Fluora is a blend of flora and fluency. Growth and mastery. The logo is a leaf with a central vein and curving stem — vocabulary taking root and growing through practice. The side veins fade in opacity, suggesting layers of meaning revealed over time.

It's a small detail, but it captures what the app is about. Language learning is cultivation. You plant words, water them with repetition, and watch comprehension grow. No shortcuts, no hacks. Just consistent practice in a space designed for focus.

Your words. Your pace. Your fluency.