npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

math-quiz-engine

v1.1.0

Published

Ultra-lightweight, zero-dependency math question generator with adaptive difficulty, cognitive distractors, mental math tips, LaTeX support, and full i18n.

Readme

🧮 math-quiz-engine

npm version License: MIT TypeScript Zero Dependencies

🌐 Language / Idioma: English · Español · Português · 中文

Ultra-lightweight, zero-dependency math question generator with adaptive difficulty, realistic cognitive distractors, mental math tips, LaTeX support, and full i18n — all in < 150 KB.


✨ Features

  • ⚡ Zero dependencies — Pure TypeScript, < 150 KB bundle, blazing fast.
  • 🌍 Multi-language (i18n) — Native support for English (en), Spanish (es), Portuguese (pt), and Simplified Chinese (zh). Questions, hints, explanations, chapter names, and answer options are all localized.
  • 🎯 24 Math Chapters — From basic arithmetic to quadratic equations, trigonometry, and logarithms.
  • 🧩 Cognitive Distractors — Wrong answers aren't random; they simulate real calculation mistakes (carry errors, PEMDAS confusion, fraction inversions, ± 10 shifts).
  • 🧠 Mental Math Tips — Every question comes with a speed-solving hint and a step-by-step explanation.
  • 📐 LaTeX Support — KaTeX / MathJax-ready representations for every question.
  • 📈 Adaptive Difficulty — Automatically adjusts between easy, normal, hard, and extreme based on player performance and response time.
  • 🎲 Seeded RNG — Reproducible question sequences for multiplayer sync, replays, or testing.
  • 📦 Universal Bundle — Works with import (ESM), require (CJS), and <script> (IIFE), with full .d.ts typings.

📦 Installation

npm install math-quiz-engine

CDN (browser):

<script src="https://cdn.jsdelivr.net/npm/math-quiz-engine/dist/index.global.js"></script>
<script>
  const engine = new MathQuizEngine.MathQuizEngine();
  console.log(engine.generateQuestion());
</script>

🚀 Quick Start

ESM (TypeScript / Modern JS)

import { MathQuizEngine, mathEngine } from 'math-quiz-engine';

// Option 1: Use the ready-made singleton
const q = mathEngine.generateQuestion();

// Option 2: Create your own configurable instance
const engine = new MathQuizEngine();
engine.setLocale('en');

const question = engine.generateQuestion({
  category: 'fractions',
  difficulty: 'hard',
  includeHint: true,
  includeLatex: true
});

console.log(question.question);     // "7/8 − 2/3"
console.log(question.answer);       // "5/24"
console.log(question.hint);         // "Butterfly method: (7×3 − 2×8) over (8×3)..."
console.log(question.locale);       // "en"

CommonJS (Node.js)

const { mathEngine } = require('math-quiz-engine');

const q = mathEngine.generateQuestion({ category: 'multiplication_ab', difficulty: 'normal' });
console.log(q.question, '=', q.answer);

📚 24 Chapters (Organized in 3 Eras)

| # | Category (category) | Era | Name | Example | |:--|:--|:--|:--|:--| | 01 | 'addition' | General | Speed Addition | 78 + 45 | | 02 | 'subtraction' | General | Subtraction & Change | 142 − 89 or cash register change | | 03 | 'multiplication_ab' | General | 2-Digit Multiplication | 14 × 17 (11-19 shortcut) | | 04 | 'division' | General | Exact Division | 342 ÷ 9 | | 05 | 'percentage' | General | Mental Percentages | 15% of 80 or 64% of 50 | | 06 | 'fractions' | General | Fractions (+, −, ×, ÷) | 2/5 + 3/4 | | 07 | 'combined_ops' | General | Order of Operations (PEMDAS) | 45 − 3 × 8 + 12 | | 08 | 'estimation' | General | Estimation & Rounding | 89 × 41 ≈ ? | | 09 | 'rule_of_three' | General | Rule of Three (Direct & Inverse) | 4 u. → $20, 12 u. → ? | | 10 | 'fraction_to_decimal' | General | Fraction → Decimal | 3/8 = 0.375 | | 11 | 'decimal_to_fraction' | General | Decimal → Fraction | 0.75 = 3/4 | | 12 | 'powers_of_ten' | General | Powers of 10 | 4 × 10³ | | 13 | 'multiplication_abc' | Bonus | 3-Digit Multiplication | 345 × 11, 124 × 25 | | 14 | 'powers' | Bonus | Powers (x², x³) | 65² (ends-in-5 trick) | | 15 | 'lcm_gcd' | Bonus | LCM & GCD | GCD(24, 36) | | 16 | 'roots' | Bonus | Square & Cube Roots | √676 or ∛216 | | 17 | 'geometry' | Bonus | Areas & Perimeters | Squares, triangles, circles | | 18 | 'magic_square' | Bonus | Magic Squares (3×3) | Find missing cell | | 19 | 'divisibility' | Bonus | Divisibility & Primes | Is 4,320 divisible by 9? / Is 91 prime? | | 20 | 'sequences' | Bonus | Sequences & Missing Terms | 3, 7, 11, … or 4, 11, ??, 25, 32 | | 21 | 'trigonometry' | Advanced | Trigonometric Ratios | sin(30°), cos(45°), tan(60°) | | 22 | 'quadratic_equations' | Advanced | Quadratic Equations | x² − 5x + 6 = 0 | | 23 | 'notable_triangles' | Advanced | Notable Triangles | 30°-60°, 45°-45°, 37°-53° | | 24 | 'logarithms' | Advanced | Mental Logarithms | log₂(32) = 5 |


🛠️ API Reference

generateQuestion(config?): GeneratedQuestion

Generates a single question with shuffled options, distractors, and metadata.

const q = engine.generateQuestion({
  category: 'logarithms',      // MathCategory | MathCategory[] | 'general' | 'bonus' | 'advanced' | 'all'
  difficulty: 'normal',        // 'easy' | 'normal' | 'hard' | 'extreme'
  locale: 'en',                // 'es' | 'en' | 'zh' | 'pt' (overrides engine default)
  optionCount: 4,              // Number of answer choices (default: 4)
  includeHint: true,           // Include mental math tip
  includeExplanation: true,    // Include step-by-step solution
  includeLatex: true,          // Include LaTeX string
  subType: 0                   // (Optional) Force specific exercise subtype
});
interface GeneratedQuestion {
  id: string;                   // Unique hash (for deduplication)
  chapterId: number;            // Chapter 1–24
  category: MathCategory;
  era: EraType;                 // 'general' | 'bonus' | 'advanced'
  subType: number;
  subTypeName: string;          // Localized subtype label
  locale: SupportedLocale;      // Language used for this question
  difficulty: DifficultyLevel;
  question: string;             // Question text
  latex?: string;               // LaTeX representation
  answer: string;               // Correct answer
  options: string[];            // Shuffled choices (includes answer)
  correctIndex: number;         // Index of correct option
  suggestedTimeSeconds: number; // Recommended time limit
  hint?: string;                // Mental math tip
  explanation?: string;         // Step-by-step walkthrough
}

generateQuiz(config): GeneratedQuestion[]

Generates a batch of deduplicated questions. Supports weighted category distribution:

const exam = engine.generateQuiz({
  count: 10,
  difficulty: 'hard',
  locale: 'en',
  categories: ['addition', 'multiplication_ab', 'percentage'],
  weights: { multiplication_ab: 6, percentage: 3, addition: 1 },
  preventDuplicates: true
});

Locale / i18n

// Set a global default locale for the engine instance
engine.setLocale('zh');
engine.getLocale(); // 'zh'

// Or override per-question
engine.generateQuestion({ category: 'divisibility', locale: 'pt' });

// Localized metadata
engine.getChapters('en');                    // All 24 chapters in English
engine.getChapter('fractions', 'pt');        // Single chapter in Portuguese
engine.getSubTypeNames('addition', 'zh');    // Subtype names in Chinese

Supported locales: 'es' (Spanish), 'en' (English), 'zh' (Simplified Chinese), 'pt' (Portuguese).

Everything is localized: chapter names, subtype labels, question text, answer options (e.g. "Yes/No" → "是/否"), hints, and explanations.


Seeded RNG

engine.setSeed(42);
const q1 = engine.generateQuestion({ category: 'multiplication_ab' });

engine.setSeed(42);
const q2 = engine.generateQuestion({ category: 'multiplication_ab' });
// q1.question === q2.question — deterministic!

engine.setSeed(null); // Back to random mode

Answer Validation

const isCorrect = engine.validateAnswer(question, userInput);
// Case-insensitive, whitespace-tolerant comparison

Adaptive Difficulty

The engine tracks streaks, accuracy, and response time to automatically adjust difficulty:

  • 3 fast correct answers → Difficulty increases (easy → normal → hard → extreme)
  • 2 wrong answers → Difficulty decreases (to maintain engagement)
  • Slow correct answers (> 30s) → No promotion (prevents premature escalation)
const newDifficulty = engine.recordAnswerResult(true, question.id, 4500);
// Returns: 'normal' | 'hard' | etc.

engine.getAdaptiveState();       // Read current streak, accuracy, history
engine.resetAdaptiveState();     // Reset to initial state

Session Management

engine.clearSessionHistory();  // Allow previously-seen questions to appear again

🏗️ Contributing

Contributions are welcome! Please open an issue or submit a pull request.

# Clone and setup
git clone https://github.com/Manz-bot/math-quiz-engine.git
cd math-quiz-engine
npm install

# Development
npm run dev          # Watch mode
npm run typecheck    # Type validation
npm test             # Run tests
npm run build        # Production build

📄 License

MIT © Manz-bot