Skip to content

About

Learn specialized English vocabulary in Persian — 246K words across 51 topics with Leitner flashcards, quizzes & pronunciation. Offline-first Material Design 3 PWA. | یادگیری لغات تخصصی انگلیسی با جعبه لایتنر

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Repository files navigation

FarsiMatrix — learn specialized English vocabulary with Leitner flashcards, quizzes and pronunciation

FarsiMatrix

Learn specialized English vocabulary in Persian — Leitner flashcards, quizzes and pronunciation, in a Material Design 3 app that works fully offline.

Open the live app →  ·  راهنمای فارسی  ·  Report a bug

Live Next.js React TypeScript Tailwind CSS Material 3 PWA License


At a glance

245,975
English → Persian entries
51
specialized topics
5-box
Leitner spaced repetition
100% offline
installable PWA
$0
no server, no database, no account

Screenshots

Home Flashcard Flashcard back, dark theme Quiz
Home & continue learning Flashcard Rate your recall 4-choice quiz
Quiz result Progress Dictionary Dynamic color
Results & mistakes review Streak & Leitner boxes Searchable dictionary Dynamic color picker
Desktop, light theme Desktop flashcard, dark theme

Features

Learn

  • Leitner flashcards with a spring-animated 3D flip. Reveal the meaning first, then rate yourself: didn't know, unsure, or knew it. Every rating moves the word between five boxes.
  • Smart filters: all cards, only words that need review (boxes 1–2), or your starred words. Cards are tracked by word, so when a word leaves a filter the next one never gets skipped.
  • Quizzes in both directions (English → Persian and Persian → English), 5–30 questions, with answers drawn from the same topic, keyboard answers (1–4), a results gauge and a review of your mistakes.
  • Dictionary view for every topic, with search across words and meanings, status filters (new, learning, mastered, starred) and pagination.
  • Progress dashboard showing your daily streak, mastered words, quiz accuracy, a Leitner box chart and your most-practised topics.

Pronunciation that works on phones

Mobile browsers make the Web Speech API unreliable, especially in installed PWAs. FarsiMatrix uses a small engine with fallbacks:

  1. Device text-to-speech first: instant and offline. It picks the best English voice, works around Android Chrome's cancel()/speak() race and the paused state after the app returns from the background, and has a watchdog for engines that never start.
  2. Recorded dictionary audio when the device can't speak (online only).
  3. If neither is available, a one-time hint explains how to enable an English TTS voice.

Methods that fail are remembered for the session, so a broken path only costs its timeout once.

Material Design 3, implemented properly

  • Dynamic color generated at runtime with Google's material-color-utilities. Choose from 8 Persian-inspired seed colors (turquoise, lapis, saffron, pomegranate…), 4 scheme styles (tonal spot, vibrant, expressive, content), 3 contrast levels, and light/dark/system modes. Custom colors (success, streak flame) are harmonized to your seed.
  • Adaptive layout: a navigation bar on phones and a navigation rail with FAB on tablets and desktop. Includes the MD3 type scale tuned for Persian script, shape tokens, tonal surfaces and state layers.
  • M3 Expressive details: shape-morphing buttons, a morphing-shape loading indicator, a wavy progress bar, expressive shape containers ("cookie", "clover", "burst"…) and spring motion.
  • Components: buttons, icon buttons, filter and assist chips, segmented buttons, dialogs with focus trap, snackbars, switches, linear and circular progress, ripple. All are hand-built on MD3 tokens with Tailwind CSS v4.
  • RTL-first and accessible: Vazirmatn typography, Persian numerals everywhere, keyboard support, visible focus, ARIA roles and prefers-reduced-motion support.

Offline-first PWA

  • Installable on Android, iOS, Windows, macOS and Linux, with app shortcuts to Flashcards and Quick quiz.
  • The service worker serves pages network-first (new releases arrive immediately), word data stale-while-revalidate, and hashed assets, fonts and icons cache-first.
  • Material Symbols are self-hosted as a ~100 KB subset, so icons work offline.
  • Your data stays on your device in localStorage. You can export and import a JSON backup; imports are validated, so a bad file can't corrupt your progress.

How the Leitner system works

flowchart LR
    N([New word]) --> B1[Box 1]
    B1 -- knew it --> B2[Box 2]
    B2 -- knew it --> B3[Box 3]
    B3 -- knew it --> B4[Box 4 · mastered]
    B4 -- knew it --> B5[Box 5 · permanent]
    B2 & B3 & B4 & B5 -- "didn't know" --> B1
Loading

Unsure keeps a word in its current box. Boxes 1–2 make up the Needs review deck, and boxes 4–5 count as mastered.

Keyboard shortcuts

Key Flashcards Quiz
Space / Enter Flip card —
1 2 3 Didn't know · Unsure · Knew it Choose option 1–3
4 — Choose option 4
← / → Next / previous card —
S Pronounce —

Persian keyboard digits (۱ ۲ ۳ ۴) work too.

Architecture

flowchart TB
    subgraph Client["Browser · Next.js 16, statically prerendered"]
        UI[React 19 UI<br/>MD3 component kit]
        Theme[Dynamic color engine]
        Speech[Pronunciation engine]
        Store[(localStorage<br/>progress · theme)]
        SW[Service worker]
    end
    Data[/"public/data/groups/*.json<br/>51 topic files, lazy-loaded"/]
    UI --> Theme
    UI --> Speech
    UI <--> Store
    UI -- fetch on demand --> SW --> Data
Loading

There's no backend. Each topic is a separate JSON file that loads only when you open it, and everything you do is saved in the browser. The app can be hosted on any static host for free.

Tech stack

Layer Choice
Framework Next.js 16 (App Router, Turbopack), React 19
Language TypeScript (strict)
Styling Tailwind CSS v4 mapped to MD3 design tokens
Color @material/material-color-utilities (dynamic color, harmonization)
Icons Material Symbols Rounded, self-hosted subset
Typography Vazirmatn via next/font
Offline Custom service worker + Web App Manifest
Effects canvas-confetti (themed to the current palette)

Getting started

Requires Node.js 20.9+.

git clone https://github.com/TssHack/FarsiMatrix.git
cd FarsiMatrix
npm install
npm run dev          # http://localhost:3000
Script What it does
npm run dev Development server with hot reload
npm run build Production build
npm run start Serve the production build
npm run lint ESLint

The service worker registers only in production builds, so development never serves stale bundles.

Project structure

farsimatrix/
├── public/
│   ├── data/
│   │   ├── categories.json        # 51 topics: titles, cluster, level, word count
│   │   └── groups/*.json          # one lazy-loaded word file per topic
│   ├── fonts/                     # self-hosted Material Symbols subset
│   ├── icons/                     # app icon (SVG master + PNG/maskable sizes)
│   ├── manifest.json              # PWA manifest with shortcuts
│   └── sw.js                      # service worker
├── src/
│   ├── app/
│   │   ├── globals.css            # MD3 tokens → Tailwind theme, motion, state layers
│   │   ├── layout.tsx             # fonts, theme boot script, providers
│   │   └── page.tsx               # app shell, hash routing, data loading
│   ├── components/
│   │   ├── m3/                    # Button, Chip, Dialog, Progress, Shape, Snackbar, Switch…
│   │   ├── AppShell.tsx           # top app bar, navigation rail & bar
│   │   ├── CategoryExplorer.tsx   # home: search, continue learning, topics
│   │   ├── FlashcardMode.tsx      # Leitner flashcards
│   │   ├── QuizMode.tsx           # quizzes & results
│   │   ├── WordListMode.tsx       # dictionary list
│   │   ├── StatsView.tsx          # progress dashboard & backup
│   │   ├── ThemeDialog.tsx        # dynamic color settings
│   │   └── AboutModal.tsx
│   ├── lib/
│   │   ├── theme.ts               # scheme generation & persistence
│   │   ├── speech.ts              # pronunciation engine
│   │   ├── storage.ts             # Leitner logic, streak, backup validation
│   │   ├── icons.ts · format.ts
│   └── types/index.ts
└── scripts/
    ├── build_data.py              # builds categories.json + per-topic word files
    └── generate_icons.py          # renders the icon set from Vazirmatn's «ف»

The icon

The mark is the Persian letter «ف», drawn from Vazirmatn Bold, with its dot replaced by a 2×2 matrix of flashcard tiles. One tile is saffron, standing for a word you've learned. To regenerate every size (PNG, maskable, Apple touch icon, favicon):

pip install fonttools          # also needs the resvg and ImageMagick CLIs
python3 scripts/generate_icons.py /path/to/Vazirmatn-Bold.ttf

Privacy

There are no accounts, no analytics and no server-side storage. The only network requests are the app's own files and, when your device has no working English voice, a recorded pronunciation from a public dictionary audio service (ssl.gstatic.com, dict.youdao.com).

Contributing

Issues and pull requests are welcome, from new topics and translation fixes to UI polish. Before opening a PR, please run:

npx tsc --noEmit && npm run lint && npm run build

Author

Ehsan Fazli (احسان فضلی) — ehsanfazli.ir · GitHub @TssHack · Telegram @devehsan

License

MIT. If FarsiMatrix helps you learn, a star on the repo is appreciated.

About

Learn specialized English vocabulary in Persian — 246K words across 51 topics with Leitner flashcards, quizzes & pronunciation. Offline-first Material Design 3 PWA. | یادگیری لغات تخصصی انگلیسی با جعبه لایتنر

Topics

Resources

Stars

6 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages