Polingu

Polingu

Featured

A Polish language learning app using spaced repetition (FSRS) to drill vocabulary, full sentences, and declensions.

React
TypeScript
Firebase
Material UI

What problem does this solve?

Polish is notoriously one of the hardest languages for English speakers to learn—it has 7 grammatical cases, 3 genders, complex verb conjugation with aspect pairs, and intricate spelling rules. Existing language apps like Duolingo gamify vocabulary memorization but fall short on drilling the deep grammatical structures that trip up learners. Resources for Polish grammar practice are sparse, disconnected, and don't leverage modern spaced repetition research. Polingu solves this by providing a purpose-built flashcard system specifically designed for Polish grammar mastery, not just vocabulary recognition.

Who is it for?

This app was built primarily for myself—an intermediate Polish learner who hit a plateau with traditional apps and needed focused practice on:

  • Declension (noun/pronoun endings across all 7 cases)
  • Verb conjugation (present, past, future, conditional, imperative across both aspects)
  • Sentence translation with contextual grammar understanding

It's ideal for any serious Polish learner who wants to move beyond basics and actually produce correct Polish, not just recognize words.

Why did you build it?

I was frustrated that no existing tool let me drill specific grammar patterns with intelligent scheduling. I wanted to:

  1. Filter practice by case, gender, or CEFR level rather than random review
  2. Tap any word and instantly see its lemma, translation, and grammatical context
  3. Use FSRS (the algorithm behind Anki) for scientifically-optimized review intervals
  4. Add custom content when I encountered new words or patterns in the wild
  5. Sync progress across devices seamlessly

I built exactly what I needed.

Technical Deep Dive

Tech Stack

Frontend: React 19 + TypeScript, Material UI, ViteBackend: Firebase (Firestore, Auth, Cloud Functions)APIs: DeepL for translation, OpenAI GPT-4 for content generationAlgorithm: ts-fsrs (Free Spaced Repetition Scheduler)

Architecture Decisions

1. Domain-Specific Schedulers

Rather than a single generic scheduler, each learning module (declension, vocabulary, sentences, conjugation) has its own scheduler implementation. Why? Each module has unique filtering requirements (cases/genders for declension, CEFR levels for sentences, verb aspects for conjugation). Separate schedulers let me handle these differences without polluting a generic abstraction with module-specific logic.

2. Factory Pattern for Custom Content Storage

Custom content (user-created cards) uses a generic factory that creates type-safe CRUD operations. Each custom content type (vocabulary, declension, sentences) instantiates this factory with its specific type, eliminating duplicated Firestore logic.

3. Server-Side Rate Limiting

Translation calls go through Firebase Cloud Functions with dual-layer rate limiting:

  • Per-minute limit: 30 requests (prevents abuse)
  • Daily character limit: 1,500 characters (controls API costs)

The rate limit state is stored in Firestore per-user and automatically resets at UTC midnight.

Interesting Challenges

Interactive Word Translation with Phrase Selection

The hardest UX challenge was making text both tappable (single word) and draggable (phrase selection) without conflicts. Solution: A context provider (TranslatableTextProvider) tracks drag state across all words in a sentence:

  1. Each <TranslatableWord> registers itself with an index
  2. On mousedown, dragging begins; mousemove over other words expands the selection
  3. On mouseup, the selected phrase is extracted and translated
  4. Clicking anywhere dismisses the phrase tooltip

This creates a natural UX where tapping shows a single word tooltip, but drag-selecting shows a phrase translation.

Translation Caching Strategy

To minimize API calls, translations are cached directly on the card documents in Firestore. The next time any user views that card, the translation is pre-populated. This creates a crowdsourced translation cache that improves over time.

Verb Conjugation Validation

Polish verbs have complex rules:

  • Perfective verbs have no present tense
  • Modal verbs (móc, musieć) have no imperative
  • Aspect pairs must cross-reference each other
  • Imperfective futures have alternative forms

I built a validation pipeline that enforces all these rules before importing verb data, catching errors like "perfective verb has present tense" or "aspect pair doesn't cross-reference."

AI-Powered Content Generation

The app uses GPT-4 via Cloud Functions for three admin-only features:

  1. Example sentence generation - Given a vocabulary word, generates 2-3 natural Polish sentences at A2-B1 level
  2. Sentence generation - Creates practice sentences filtered by CEFR level and topic tags
  3. Curriculum discovery - Analyzes existing content tags and suggests missing grammar concepts (particularly Polish-specific features like verbal aspect, motion verbs, impersonal constructions)

All responses are validated server-side to ensure proper structure before returning.

Four Learning Modules
  • Declension — Master noun and pronoun endings across all 7 Polish cases (Nominative, Genitive, Dative, Accusative, Instrumental, Locative, Vocative) with fill-in-the-blank flashcards and grammar hints explaining why each case is used.
  • Conjugation — Drill verb forms across present, past, future, conditional, and imperative tenses. Handles both imperfective and perfective aspects, including irregular verbs and modal verbs with their quirks.
  • Vocabulary — Learn common Polish words with example sentences, part of speech labels, and gender information. Cards show the word in context so you understand usage, not just definitions.
  • Sentences — Practice translating complete Polish sentences, organized by CEFR level (A1 through C2). Each sentence includes detailed word-by-word annotations with lemmas and grammar notes.
FSRS Spaced Repetition

Uses the Free Spaced Repetition Scheduler—the same algorithm powering Anki 23+. After revealing an answer, rate your recall:

  • Again — Forgot (card repeats in current session)
  • Hard — Struggled to remember
  • Good — Remembered with effort
  • Easy — Instantly recalled

The algorithm calculates optimal review intervals based on your history, maximizing retention while minimizing study time.

Tap-to-Translate

Tap any Polish word to see its English translation instantly. The translation appears in a tooltip with contextual meaning based on the surrounding sentence.

Drag-select phrases for multi-word translations—useful for idioms and expressions that don't translate word-by-word.

Translations are cached to Firestore, so repeated lookups are instant and don't consume API quota.

Bidirectional Practice

Vocabulary and sentences support two practice directions:

  • Recognition (Polish → English) — See Polish, produce the English meaning
  • Production (English → Polish) — See English, produce the Polish translation

Production mode is harder but builds active recall—essential for actually speaking Polish, not just understanding it.

Smart Filtering

Customize what you study without breaking your review schedule:

  • Filter declension cards by case, gender, and number
  • Filter sentences by CEFR level (A1–C2)
  • Filter conjugation by tense, aspect, and verb class

Filters only affect new cards. Due reviews always appear regardless of filters—you can't skip cards you've already started learning.

Custom Content

Add your own learning material alongside system content:

  • Create custom vocabulary with part of speech, gender, and notes
  • Create custom declension fill-in-the-blank cards
  • Create custom sentences with Polish/English pairs

Custom cards integrate seamlessly with the SRS system and are prioritized in session order so you see your own content first.

Flexible Study Modes

Normal mode shows due reviews plus new cards up to your daily limit. But when you need more flexibility:

  • Practice mode — Drill cards without affecting your SRS progress (great for pre-exam cramming)
  • Practice Ahead — Review future cards before they're officially due
  • Learn Extra — Add more new cards beyond your daily limit when you're feeling ambitious
Reference Cheat Sheets

Quick-access reference materials available from the bottom menu:

  • Declension endings — Complete tables for masculine, feminine, and neuter nouns
  • Consonants — Soft, hard, and hardened consonant categories (crucial for spelling)
  • Y/I rules — When to use Y vs I in Polish spelling
  • Conjugation patterns — Regular verb endings organized by class
Cloud Sync

Sign in with Google to sync progress across devices. All review data is stored in Firebase Firestore and works offline with automatic sync when you're back online.

AI-Powered Tools (Admin)
  • Example generation — GPT-4 creates natural Polish sentences for vocabulary words
  • Sentence generation — Generate practice sentences by CEFR level and topic tags
  • Curriculum discovery — AI analyzes existing content and suggests missing grammar concepts for comprehensive coverage


Building for Yourself is Different

This was the first project where I was genuinely the primary user. Every feature decision came from real frustration—not hypothetical user stories. When I added the "tap any word to translate" feature, it wasn't because it seemed cool; it was because I kept alt-tabbing to Google Translate mid-study session and losing focus.The lesson: Building for yourself removes the guesswork. You know immediately when something doesn't work because you feel the friction. The flip side is you have to be careful not to over-engineer for your specific edge cases.

Spaced Repetition is Fascinating (and Humbling)

I went deep on spaced repetition research while building this. The FSRS algorithm models memory as an exponential decay curve, and the math behind optimal review intervals is genuinely beautiful. But it also made me realize how much of traditional studying is wasted effort—cramming the night before is statistically terrible for long-term retention.The lesson: Sometimes building a tool teaches you more about the domain than the code. I understand how memory works now in a way I never did before.

AI as a Power Tool, Not a Crutch

I used GPT-4 for content generation (example sentences, curriculum suggestions), but every piece of AI output goes through validation before hitting the database. Early on, I trusted the AI too much and ended up with grammatically incorrect Polish sentences in my deck.The lesson: AI is great for generating candidates, but you need guardrails. Server-side validation, structured output parsing, and human review for anything user-facing.

State Management for Interactive UX is Hard

The tap-to-translate feature sounds simple: click a word, show a tooltip. But then I wanted drag-to-select for phrases. Now I needed to track: which word started the drag, which words are currently selected, whether we're in "phrase mode" vs "word mode," and how to dismiss tooltips properly. The TranslatableTextContext provider went through three rewrites.The lesson: Interactive features that feel simple to use are often complex to build. Budget extra time for anything involving drag, selection, or multiple interaction modes.

Content is Harder Than Code

I spent more time curating and validating Polish verb conjugations than writing the conjugation driller itself. Each verb has ~50 forms across tenses/persons/genders. Modal verbs don't have imperatives. Perfective verbs don't have present tense. Aspect pairs need to cross-reference each other.I ended up building CLI tools (verbs:validate, verbs:import) just to manage the content pipeline.The lesson: For content-heavy apps, the tooling around the content is as important as the app itself. Invest early in validation and import workflows.

Ship the Thing You'll Actually Use

I've started and abandoned many side projects. This one survived because I use it every day. The secret wasn't motivation—it was choosing a project where shipping meant I got something I genuinely wanted.The lesson: Personal projects succeed when the reward is intrinsic. If you wouldn't use your own app, you probably won't finish it.