homezdebarth@gmail.comClick to reveal contact form

Links

Introduction

I needed a simple language learning app to improve my vocabulary and pronunciation. None of the apps I tested fit my needs, so I decided to make one myself.

Main Idea

In my opinion, language learning is about the sheer amount of practice and repetition. Personally, I prefer to get these repetitions in a fast-paced 20-minute drill rather than an hour-long learning game. It is entirely possible to practice 400 words or 200 sentences in 20 minutes.


Basic principles:

Flashcards

  • Flashcards are the most time-efficient method, enabling fast-paced practice. Both vocabulary and grammar are taught in one continuous flow of flashcards. No time is wasted on methods like crosswords or games. These may be more fun, but with flashcards, you get more practice in the same amount of time.
  • Listening and speaking

  • There is an exclusive emphasis on listening and speaking. Writing slows down practice and is relatively easy compared to speaking.
  • User Dashboard

    Procvičovat / Practice

    The only practice button. Will provide a continuous practice flow, eliminating the need to switch focus between tasks.

    Přehled pokroku / Progress Overview

    The User Dashboard also shows progress in two areas. The first is progress in the last four levels based on learned words or sentences. Currently, these are CEFR levels, but I plan to change this to about 100 generic progress levels. The second is progress in daily repetition blocks. At the moment, it shows about 40 daily blocks per 10 items, which equals 400 repetitions per day and about 20 minutes of practice. Essentially, the first is linked to overall progress, and the second to daily practice. In the grand scheme, it’s just about providing motivating feedback to the user.

    User Dashboard

    Přehled / Overview

    The overview allows you to look up any already unlocked word or grammar block and reset its progress if needed.

    Word OverviewGrammar Overview

    Practice Card

    Context guide

    Separate help pages are rarely read, so I generally use contextual help whenever possible.

    Practice flow

    You are presented with a word or sentence, alternating between written Czech and listening to English for each word. When you reveal the translation, the full translation is displayed.


    Using the plus or minus buttons, you evaluate your knowledge. Plus increases the interval for the next repetition, while minus decreases it. The app automatically adjusts the algorithm based on your input.

    Practice Card 1Practice Card 2

    Features tested, but discarded

    Automatic pronunciation feedback

    I tested several tools (Vosk, Gentle, Google Speech-to-Text API). All are too inaccurate to be truly useful. It would be great to get immediate feedback on my pronunciation, but for now, listening and immediately repeating works quite well.

    Technical

    Scripts

    Python, Google API

    Translation, pronunciation, and audio files are all generated using the Google Translate API and other tools.

    Authentication

    Firebase (Google Auth)

    Database

    PostgreSQL, Supabase for hosting

    The SQL database schema is quite simple, with just a few tables, but it provides significant flexibility in organizing the practice flow. Generally, some items are grouped together in various grammar blocks and inserted into the basic practice sequence.

    Database Scheme

    Backend

    Node.js, Express.js, Winston Logger, Railway for hosting

    The function getItemsRepository is crucial for combining individual words and sentences.

    Backend Logic

    Frontend

    React, React Router, TypeScript, Vercel for hosting

    PracticeCard.tsx is the core component responsible for the entire frontend practice logic. It employs useStates, useEffects, useCallbacks, useRefs, and custom hooks to manage the practice flow.

    Practice Card Logic

    Testing

    Vitest, Jest, React Testing

    I initially created numerous tests but realized that constant feature changes required rewriting them, which consumed about 50% of my time. Once the app stabilizes, I plan to add comprehensive tests to cover all necessary cases.

    What I've learned

    1. The technical solution is the easy part; the real challenge lies in properly defining the desired features. Start with a "minimum viable product." Even if you have a plan, it will likely change as soon as you begin testing.

    2. Writing clean code saves a lot of time in the long run. It's worth taking the time to think things through and redo work properly instead of rushing.

    version v0.1.0

      Changes

    • Added multiple languages support
    • Added skip button

    Testing

    I have added support for multiple languages for testing purposes. Since I already know English too well, I cannot properly test myself on it. Therefore, I added Spanish to test the app on myself. It works well if the user is disciplined in evaluating his knowledge.

    version v0.2.0

    Changes

    • UI changes - more information on Practice Card
    • Winston logger changes

    Missing data

    he app just needs to be filled with more data. I have already added some English and Spanish words, but in the future, I will look for cooperation with someone who specializes in specific languages.

    version v0.3.0

    Changes

    • Added options to reset progress of - language, grammar block, individual vocabulary

    version v0.4.0

    Changes

    • Added userDashboard help
    • Complete refactor of backend and frontend

    version v0.5.0

    Changes

    • Added User Avator Picture from Google Accounts
    • Added word count information to WordList
    • UI - multiple small changes

    version v0.6.0

    Changes

    • Added WordCard - new component for individual WordList items
    • Added HelpOverlay - moved help icon just outside of card outline
    • Disabled language options - for now focus only on English language
    • UserRestart - moved to UserOverview from UserSettings
    • Changes to - UserAvatar, Light mode colors, UserDashboard

    version v0.7.0

    Changes

    • Improved database structure with
      • user_blocks – marks started grammar blocks
      • notes – separates grammar explanations from grammar blocks, enabling more focused grammar practice with the same explanation
      • items.block_id – vocabulary items are now also organized into blocks, enabling cleaner organization
      • blocks.language_id – language is now strictly determined by blocks; currently, there is only a single language (English). Language selection is present in the code but disabled for now.
      v0.7.0 Database Scheme
    • Changed levels from CEFR to smaller numbered levelsv0.7.0 User Dashboard
    • Changed daily blocks organization from an array to an object for a more consistent style.