An adaptive math learning platform with interactive puzzles, real-time multiplayer, and step-by-step explanations.
|
🧭 Orientation |
🧠 Capabilities |
🤝 Community |
Tenali (named after the legendary Tenali Raman — the witty Indian scholar who outwitted entire courts with logic) is an adaptive math learning platform featuring 69 algorithmically-generated puzzle types, real-time multiplayer battles, and step-by-step solutions for every problem. Every question is generated on the fly — there is no question database — so practice is infinite and never repeats. Difficulty adapts to each learner in real time.
It is built to run on a single VPS — tenali.fun — with one Node process serving the React app, the puzzle APIs, the JWT auth, the Socket.IO Battle Arena, and the multi-language code playground.
| 818 commits |
61 PRs merged |
20 GitHub contributors |
⭐ 6 stars |
🍴 58 forks |
🐛 50 open issues |
🤖 Numbers above refresh automatically on every push to main via github-actions[bot] — no manual edits required.
Frontend : React 19 + Vite 8 + framer-motion + Three.js + mafs + face-api.js
Backend : Node.js 20+ · Express 5 · Mongoose 9 · Socket.IO 4
Security : JWT (bcrypt 10 rounds) · express-rate-limit · CORS allowlist
Data : MongoDB with full in-memory fallback
Sandbox : 50+ languages via /api/playground2
A learner goes through four simple stages every time they play:
┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ 🌐 Open │───▶│ 📐 Pick │───▶│ ▶️ Play │───▶│ 🏆 Earn │
│tenali.fun│ │ topic │ │ 20 Qs │ │+ badge │
└──────────┘ └──────────┘ └──────────┘ └──────────┘
That's it. Everything else — login, difficulty, scoring, badges — happens automatically inside the Play box.
- Lands on the home grid — 90+ colorful topic cards (blue = arithmetic, green = geometry, purple = algebra, orange = games)
- Optional login with JWT — guest mode works fully without an account
- Filter by search or browse the guided journey
Choose any of these modes from the home grid:
| Mode | What you do |
|---|---|
| 🎯 Goal Practice | Hit a target score on a chosen topic |
| ⚔️ Battle Arena | Live 1-vs-1 fastest-finger duel (Socket.IO) |
| 🔍 Detective Agency | Solve story-driven math mysteries |
| 🧩 Math Riddles | Find the hidden rule in a puzzle |
| 📚 Guided Journey | Linear curriculum — unlock the next concept only after mastering the current one |
| 🎲 Random Mix | Quiz that adapts to your weakest topics |
| 🛠️ Custom Lesson | Hand-pick topics and question counts |
- ✅ Correct → score goes up (+0.15 to +0.5)
- ❌ Wrong → score goes down (−0.4 to −0.6)
- 💡 Tap "Solve" at any time for a step-by-step explanation
- 📈 Difficulty auto-adjusts with every answer:
easy → medium → hard → extrahard
- 🏆 Results screen — coins, XP, streak
- 🥇 Badge — bronze → silver → gold per topic
- 📊 Progress saved — persisted in MongoDB for next time
- ➡️ Loop — pick another topic and play again
Each quiz instance maintains a float adaptScore (0 – 3). Correct answers add +0.15 to +0.5; wrong answers subtract −0.4 to −0.6. The score maps to bands easy → medium → hard → extrahard, which drives the difficulty query parameter for every new question.
BattleApp.jsx delivers real-time multiplayer using Socket.IO. Two players see the same question; the first correct answer wins the round. Streak-based matchmaking.
detective-app.jsx ships story-driven mystery puzzles — each case is a chain of math clues, solving one unlocks the next.
conceptPlay.js + conceptSession.js provide a 5-stage concept mastery loop: Predict → Grid → Guided → Independent → Review.
Linear curriculum with concept checkpoints. Completing one unlocks the next. Server enforces progression via UserTopicProgress (locked → blue → bronze → silver → gold).
Wrap any POST *-api/check call with { solve: true } and the server returns a step-by-step walkthrough from generateExplanation() — covers 50+ puzzle types.
lib/spacingLadder.js promotes recently-missed questions back into rotation, driven by BKT (Bayesian Knowledge Tracing — lib/bkt.js).
Optional exam-mode supervision with webcam + face-api.js emotion detection, focus / tab-switch event logging, and an admin-only /api/proctor/sessions dashboard.
Coins for every correct answer, XP & streak tracking, pinned badges, and album-style Collections.
Random Mix pulls a question from your weakest areas. Custom Lesson lets you pick exactly which topics appear and how many of each.
7,662 curated vocab words with definitions and contextual clues, served from vocab/questions/. Secondary feature — for breaks between math practice.
991 General Knowledge questions across geography, history, science, sports and culture. Secondary feature — for variety between math sessions.
Per-topic mastery, public badge board, collection completion.
Run code in 50+ languages via /api/playground2/run.
LcmHcfApp, LinearAlgebraApp (56 missions × 6 modules), GeometryApp, ProbLabApp, PythagLabApp, BearingsLabApp, NetBuilderApp, ShapeSlicer3D, ShapeTranslatorApp, ScribbleGuessApp, Curiosity.jsx, SudokuApp, VisualMathLabRedux, PlaygroundApp, LocalCompilerApp.
Built-in locale switching (/src/locales) for multi-language classrooms.
Keyboard navigation, ARIA roles, reduced-motion friendly animations.
JWT auth with fail-fast in production, express-rate-limit, CORS allowlist, bcrypt password hashing, env-sourced seed users.
Every puzzle has the same two-route contract:
GET /<type>-api/questionandPOST /<type>-api/check. To fetch a step-by-step explanation, set{ solve: true }in the POST body.
➕ Arithmetic & Number (20 types)
| Type | Endpoint | |
|---|---|---|
| 1 | Addition | /addition-api |
| 2 | Column Addition | /column-addition-api |
| 3 | Column Subtraction | /column-subtraction-api |
| 4 | Column Multiplication | /column-multiplication-api |
| 5 | Column Division | /column-division-api |
| 6 | Multiplication Tables | /multiply-api |
| 7 | Decimals | /decimals-api |
| 8 | Gym Decimals (MCQ) | /gymdecimals-api |
| 9 | Fractions | /fractionadd-api |
| 10 | Fractions-Add Gym (MCQ) | /fracaddgym-api |
| 11 | Basic Arithmetic | /basicarith-api |
| 12 | Indices | /indices-api |
| 13 | Indices Gym (MCQ) | /indicesgym-api |
| 14 | Surds | /surds-api |
| 15 | Sequences | /sequences-api |
| 16 | Ratio & Proportion | /ratio-api |
| 17 | Percentages | /percent-api |
| 18 | Profit & Loss | /profitloss-api |
| 19 | Banking (RD) | /banking-api |
| 20 | GST | /gst-api |
💰 Commerce & Statistics (8 types)
| Type | Endpoint | |
|---|---|---|
| 21 | Shares & Dividends | /shares-api |
| 22 | Rounding | /rounding-api |
| 23 | Standard Form | /stdform-api |
| 24 | Speed, Distance, Time | /sdt-api |
| 25 | Number Bases | /bases-api |
| 26 | HCF & LCM | /hcflcm-api |
| 27 | Prime Factors | /primefactor-api |
| 28 | Bounds | /bounds-api |
📐 Algebra (15 types)
| Type | Endpoint | |
|---|---|---|
| 29 | Variation | /variation-api |
| 30 | Linear Equations (one var) | /lineareq-api |
| 31 | Line Equations (m, c) | /lineq-api |
| 32 | Linear Equations Gym (MCQ) | /lineqgym-api |
| 33 | Simultaneous Equations | /simul-api |
| 34 | Quadratic Evaluation | /quadratic-api |
| 35 | Quadratic Formula | /qformula-api |
| 36 | Polynomial Multiplication | /polymul-api |
| 37 | Polynomial Factorisation | /polyfactor-api |
| 38 | Polynomials Gym (MCQ) | /polygym-api |
| 39 | Remainder Theorem | /remfactor-api |
| 40 | Binomial Theorem | /binomial-api |
| 41 | Functions Evaluation | /funceval-api |
| 42 | Functions Gym (MCQ) | /funcgym-api |
| 43 | Variation Direct/Indirect | /variation-api |
📊 Geometry & Trig (14 types)
| Type | Endpoint | |
|---|---|---|
| 44 | Trig (SOH-CAH-TOA) | /trig-api |
| 45 | Inverse Trig | /invtrig-api |
| 46 | Circular Measure | /circmeasure-api |
| 47 | Inequalities | /ineq-api |
| 48 | Coordinate Geometry | /coordgeom-api |
| 49 | Section Formula | /section-api |
| 50 | Linear Programming | /linprog-api |
| 51 | Probability | /prob-api |
| 52 | Permutations & Combinations | /permcomb-api |
| 53 | Statistics | /stats-api |
| 54 | Sets | /sets-api |
| 55 | Bearings | /bearings-api |
| 56 | Matrices | /matrix-api |
| 57 | Linear Algebra (56 missions) | /linearalgebra-api |
🧮 Linear Algebra & Vectors (6 types)
| Type | Endpoint | |
|---|---|---|
| 58 | LA Mission Quiz | /la-mission-quiz-api |
| 59 | Vectors | /vectors-api |
| 60 | Dot Products | /dotprod-api |
| 61 | Dot Products Gym (MCQ) | /dotprodgym-api |
| 62 | Transformations | /transform-api |
| 63 | Mensuration | /mensur-api |
🎯 Calculus, Puzzles & Games (15+ types)
| Type | Endpoint | |
|---|---|---|
| 64 | Pythagoras' Theorem | /pythag-api |
| 65 | Heron's Formula | /heron-api |
| 66 | Circle Theorems | /circleth-api |
| 67 | Circle Geometry | /circle-api |
| 68 | Logarithms | /log-api |
| 69 | Differentiation | /diff-api |
| 70 | Differential Equations | /diffeq-api |
| 71 | Integration | /integ-api |
| 72 | Limits | /limits-api |
| 73 | Conic Sections | /conics-api |
| 74 | Complex Numbers | /complex-api |
| 75 | Angles | /angles-api |
| 76 | Triangles | /triangles-api |
| 77 | Polygons | /polygons-api |
| 78 | Congruence | /congruence-api |
| 79 | Similarity | /similarity-api |
| 80 | Visual Math | /visual-math-api |
| 81 | Conceptual | /concept-api |
| 82 | Vocabulary (7,662 words) | /vocab-api |
| 83 | GK (991 questions) | /gk-api |
| 84 | Tatsavit | /tatsavit-api |
| 85 | Sudoku | /sudoku-api |
| 86 | Transfer scenarios | /transfer-api |
| 87 | Darts | /darts-api |
| 88 | Riddles | /riddle-api |
| 89 | Square Root | /sqrt-api |
| 90 | Squaring | /squaring-api |
| 91 | Curiosity | /curiosity-api |
Frontend proxy: every
*-apiis forwarded from Vite (port5173) → Express (port4000) — seeclient/vite.config.js.
┌──────────────────────────────────────────────────────────────────┐
│ Browser (React 19 + Vite) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ HomeGrid │ │ QuizApps │ │ Battle │ │ Detec- │ │
│ │ App.jsx│ │ factory │ │ Arena │ │ tive │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └──────────────┴────────────┴─────────────┘ │
│ │ │
│ axios / socket.io │
└──────────────────────────┼───────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────┐
│ Express Server (Node 20+, port 4000) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Solve MW │ │ Rate Limiter │ │ JWT Auth │ │
│ │ (explain) │ │ + CORS │ │ (bcrypt) │ │
│ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ │
│ └────────────┬────┴────────────┬────┘ │
│ ▼ ▼ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ 69 puzzle routers (GET ?question, POST ?check) │ │
│ └──────┬───────────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼───────────────────────────────────────────────┐ │
│ │ Utility layer: gcd, lcm, simplify, randomInt, ... │ │
│ └──────┬───────────────────────────────────────────────┘ │
│ │ │
│ ┌──────▼───────────────────────────────────────────────┐ │
│ │ Data: 991 GK JSON · 7,662 vocab JSON · algorithm │ │
│ └──────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────┐ │
│ │ MongoDB (Mongoose 9) │ │
│ │ users · progress · ... │ │
│ └─────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
🔀 Repo hierarchy:
vicharanashala/tenali ← canonical main repo (PRs land here)If you just want to run Tenali locally, the commands below work fine. If you plan to contribute, please fork
vicharanashala/tenali(not this repo) and open PRs back to upstream — see 🤝 Contributing.
- Node.js 20+
- MongoDB (optional — falls back to in-memory mode)
- npm
# Option A — clone the canonical upstream (recommended for fresh installs)
git clone https://github.com/vicharanashala/tenali.git
cd tenali
### Install
```bash
cd server && npm install
cd ../client && npm installcd server && npm install
cd ../client && npm installCreate server/.env:
PORT=4000
MONGO_URI=mongodb://127.0.0.1:27017/tenali
JWT_SECRET=replace-me-with-a-long-random-string
JWT_TTL=14d
TENALI_SEED_USERS=alice:secret123,bob:secret456# Terminal A — backend
cd server && node index.js # → http://localhost:4000
# Terminal B — frontend
cd client && npm run dev # → http://localhost:5173The Vite dev server proxies every /<type>-api and /api call to :4000.
cd client && npm run build
cd ../server && NODE_ENV=production JWT_SECRET=... node index.jsThe Express server serves client/dist/ statically. See render.yaml for the Render deployment template.
cd client && npm run lintFive-step recipe:
- Server — Add
GET /<type>-api/questionandPOST /<type>-api/checkinserver/index.js. Difficulty (0 – 3) drives parameter ranges. - Proxy — Add the new prefix to
client/vite.config.jsproxy list. - Component — Build a quiz component with the
makeQuizApp({ title, apiPath, diffLabels, placeholders, answerField })factory inclient/src/App.jsx. - Register — Map the key in
modeMapand add an entry toregularAppsfor the home grid. - Explain — Add a
casetogenerateExplanation()so the Solve button works.
tenali.fun (DNS → <production IP — redacted from public docs>)
└── Nginx (SSL via Let's Encrypt)
└── proxy_pass http://127.0.0.1:4000
└── tenali.service (systemd, runs as tenali user)
└── node /home/tenali/tenali/server/index.js
🔒 Security note: The droplet IP, SSH host, and admin SSH credentials live only in GitHub Actions secrets (
SSH_HOST,SSH_USER,SSH_PRIVATE_KEY) — never committed to source.
All contributor data below was fetched live from the GitHub Contributors API. Each contributor card shows the real name (from their GitHub profile), their GitHub ID, and the commits they contributed.
🔄 Bot refresh cadence: Every 12 hours (UTC 00:00 & 12:00) via cron. Only repo admins/maintainers can trigger manually — see CONTRIBUTORS.md → Bot refresh cadence.
| 🏆 Commits | 🔀 Merged PRs | 👥 Contributors | 🧩 Puzzles | 📚 Vocab | 🌍 GK |
|---|---|---|---|---|---|
| 818 | 61 | 20 | 69 | 7,662 | 991 |
Live data — last regenerated 2026-08-03 · auto-refreshed by github-actions[bot] on every push to main and every 12h.
| # | 👤 Real Name | 🔗 GitHub ID | 📝 Commits | 🔀 PRs | 🏷️ Role |
|---|---|---|---|---|---|
| 🥇 | S. R. S. Iyengar ↳ also commits as sudarshan |
sudarshansudarshan | 281 | 0 | Lead Architect · Curriculum Author · 69 puzzle families |
| 🥈 | Mudit Agrawal | muditagrawal2007 | 168 | 13 | Maintainer · Battle Arena · Linear Algebra · Sudoku · Playground |
| 🥉 | Jinal Gupta | jgupta05072003-code | 83 | 0 | Upstream Repo Maintainer & PR Reviewer |
| 4. | **Lakshmi Varshini Nandula ** | varshini-nandula | 43 | 1 | Profile Showcase & Offline Storage |
| 5. | Sameer Mishra | 24F3005086 | 36 | 4 | i18n · Accessibility · Concept Labs |
| 6. | Vaibhav Satish ↳ also commits as Vaibhav |
Vaibhav-sa30 | 35 | 2 | Vachana Literacy Lab & Vocabulary |
| 7. | DIPTOSUBHRO DATTA ↳ also commits as Dipto Subhro |
diptosubhro-ctrl | 33 | 1 | Tutorial System + Noise Filter Refactor |
| 8. | Ritish Karmakar | Ritish007-svg | 27 | 1 | Percentages Level-wise Explanation |
| 9. | saniyajos ↳ also commits as SaniyaJos |
saniyajos | 22 | 0 | — |
| 10. | K C Dharshan | KCDharshan9 | 21 | 1 | Tap-to-Define Word Glossary |
| 11. | Ahana Banerjee | ahana4banerjee | 20 | 2 | Goal Practice & Learning Journey |
| 12. | Shubh Dixit ↳ also commits as Shubh dixit |
Shubhdix9 | 16 | 2 | Premium UI Suite + Word Games |
| 13. | github-actions-bot- ↳ also commits as github-actions[bot] |
github-actions-bot- | 8 | 0 | — |
| 14. | SemiColonSlayer | sharonyamita-spec | 6 | 1 | Math Detective Agency |
| 15. | PANDRAJU POORVI PRAVALLIKA | poorvipravallika06 | 6 | 1 | HCF/LCM Interactive Module |
| 16. | Rukmender T | RukmenderT | 5 | 1 | Curiosity Mode |
| 17. | S. Hamsalekha ↳ also commits as S Hamsalekha |
S-Hamsalekha-annamai | 3 | 1 | Track User Progress |
| 18. | Krishna Gelra | KrishnaG-101 | 3 | 1 | Language Puzzles Framework |
| 19. | Anshul Kanodia | AnshulKanodia | 2 | 0 | Geometry Game Restoration |
| 20. | Vasuki | vasuki-tenali | 1 | 0 | Infra contributor |
📋 The full per-contributor cards (avatars, real names, GitHub IDs, location, top features, merged-identity notes) live in a separate file:
👉 See CONTRIBUTORS.md for the full profile cards
The leaderboard below stays here as the quick-at-a-glance summary — auto-refreshed by
github-actions[bot]on every push tomainand every 12 hours.
Feature ████████████████████████████ 24 PRs
Fix / Bug ███████████████████ 16 PRs
Chore / Infra █████ 4 PRs
Docs █ 1 PR
⚠️ The canonical upstream isvicharanashala/tenali— that's where all PRs land.This repo (
muditagrawal2007/Tenali_123) is a personal fork, not the canonical main repo. To contribute, please forkvicharanashala/tenaliand open your PR there — direct pushes to this fork are not reviewed.
Step-by-step fork-first workflow (upstream → your fork → PR back):
# 1. Fork the CANONICAL upstream on GitHub
# → click the "Fork" button on https://github.com/vicharanashala/tenali
# → this creates https://github.com/<your-username>/tenali
# 2. Clone YOUR fork (not this one)
git clone https://github.com/<your-username>/tenali.git
cd tenali
# 3. Add the canonical upstream as the `upstream` remote
# (so you can pull in the latest changes)
git remote add upstream https://github.com/vicharanashala/tenali.git
git remote add origin https://github.com/<your-username>/tenali.git
# 4. Verify remotes
git remote -v
# origin https://github.com/<your-username>/tenali.git (fetch)
# origin https://github.com/<your-username>/tenali.git (push)
# upstream https://github.com/vicharanashala/tenali.git (fetch)
# upstream https://github.com/vicharanashala/tenali.git (push)
# 5. Stay synced with upstream main
git fetch upstream
git checkout main
git merge upstream/main
# 6. Create a feature branch
git checkout -b feat/amazing
# 7. Make changes, then commit
git add .
git commit -m "feat: add amazing new puzzle"
# 8. Push to YOUR fork
git push origin feat/amazing
# 9. Open a Pull Request from <your-username>/tenali:feat/amazing
# → vicharanashala/tenali:mainEvery merged PR bumps your spot in the leaderboard 🏅
💡 Already forked
muditagrawal2007/Tenali_123? You can re-target your fork:Settings → General → Redirect this repository to vicharanashala/tenali.
Built with ❤️ by the Tenali community
🌐 tenali.fun · ⭐ If Tenali helps your classroom or your kids, drop a star — it fuels the next release.