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

@coffeeandfun/maths-captcha

v2.0.0

Published

Maths-Captcha is a simple Node.js module that generates random math questions to verify human interaction. It creates math problems like addition, subtraction, multiplication, and division, and checks if the user's answer is correct. Ideal for adding a qu

Readme

🧮 @coffeeandfun/maths-captcha

A simple, fun way to verify humans with math problems!

@coffeeandfun/maths-captcha is a lightweight Node.js module that creates random math questions and checks user answers. It's perfect for replacing traditional CAPTCHAs with something more engaging and accessible. Instead of squinting at distorted text, your users solve simple math problems like "What's 7 + 3?"


📦 Installation

Getting started is super easy! Just install via npm:

npm install @coffeeandfun/maths-captcha

🏃‍♂️ Quick Start

Here's how to get up and running in under 30 seconds:

// Import the functions you need
import { generateRandomMathQuestion, validateAnswer } from '@coffeeandfun/maths-captcha';

// 1. Generate a math question
const question = generateRandomMathQuestion();
console.log(`Question: ${question.question}`);
// Output: "Question: 7 + 3"

// 2. Get the user's answer (from a form, input, etc.)
const userAnswer = "10"; // This would come from user input

// 3. Check if they got it right
const isCorrect = validateAnswer(question, userAnswer);
console.log(`Correct: ${isCorrect}`);
// Output: "Correct: true"

🌟 Real-World Example

const express = require('express');
const { generateRandomMathQuestion, validateAnswer } = require('@coffeeandfun/maths-captcha');

const app = express();

// Generate a question for the user
app.get('/captcha', (req, res) => {
  const question = generateRandomMathQuestion();
  req.session.captcha = question; // Store in session
  res.json({ question: question.question });
});

// Verify the user's answer
app.post('/verify', (req, res) => {
  const userAnswer = req.body.answer;
  const isCorrect = validateAnswer(req.session.captcha, userAnswer);
  
  if (isCorrect) {
    res.json({ success: true, message: "Correct! You're human! 🎉" });
  } else {
    res.json({ success: false, message: "Try again! 🤔" });
  }
});

📚 Complete API Reference

Core Functions

generateRandomMathQuestion(precision?)

Creates a random math question with smart defaults.

const question = generateRandomMathQuestion();
console.log(question);
// {
//   question: "15 + 8",
//   answer: "23",
//   numericAnswer: 23,
//   operation: "+",
//   operands: [15, 8]
// }

Parameters:

  • precision (optional): Number of decimal places for division (default: 2)

Returns: Question object with all the details you need

validateAnswer(question, userAnswer)

Checks if the user's answer is correct (strict mode for backward compatibility).

const question = { question: "10 + 5", answer: "15" };

validateAnswer(question, "15");    // ✅ true
validateAnswer(question, "15.0");  // ❌ false (strict integer mode)
validateAnswer(question, "16");    // ❌ false

validateAnswerFlexible(question, userAnswer)

More user-friendly validation that accepts different formats.

const question = { 
  question: "10 / 4", 
  answer: "2.50",
  numericAnswer: 2.5,
  operation: "/"
};

validateAnswerFlexible(question, "2.5");     // ✅ true
validateAnswerFlexible(question, "2.50");    // ✅ true  
validateAnswerFlexible(question, "2.500");   // ✅ true
validateAnswerFlexible(question, "2.49");    // ❌ false

Advanced Features

generateMultipleQuestions(count, precision?)

Generate several questions at once.

const questions = generateMultipleQuestions(3);
// Returns array of 3 question objects

generateQuestionWithConstraints(options)

Create questions with specific requirements.

const easyQuestion = generateQuestionWithConstraints({
  operations: ['+', '-'],        // Only addition and subtraction
  numberRange: { min: 1, max: 20 }, // Small numbers only
  maxResult: 50                  // Keep results under 50
});

validateAnswerWithFeedback(question, userAnswer)

Get detailed information about why validation failed.

const result = validateAnswerWithFeedback(question, "wrong");
console.log(result);
// {
//   isValid: false,
//   reason: "Invalid numeric format",
//   userInput: "wrong",
//   expected: "15"
// }

getQuestionStats(question)

Analyze question difficulty and properties.

const stats = getQuestionStats(question);
console.log(stats);
// {
//   difficulty: 4,        // Scale of 1-10
//   hasDecimals: false,
//   operands: { num1: 15, num2: 8 },
//   operation: "+",
//   result: 23
// }

Configuration

setConfig(options) & getConfig()

Customize the behavior to fit your needs.

const { setConfig, getConfig } = require('maths-captcha');

// Customize settings
setConfig({
  DIVISION_PRECISION: 3,           // 3 decimal places for division
  NUMBER_RANGE: { min: 1, max: 50 }, // Smaller numbers
  OPERATIONS: ['+', '-', '*'],     // No division
  AVOID_NEGATIVE_RESULTS: true     // Keep results positive
});

// Check current settings
const config = getConfig();
console.log(config);

Utility Functions

normalizeNumericString(str)

Clean up numeric strings by removing trailing zeros.

normalizeNumericString("5.00");    // "5"
normalizeNumericString("3.40");    // "3.4"

checkIfSolvedCorrectly(question, userAnswer)

Alias for validateAnswer() - same functionality.


🎨 Customization Examples

Easy Mode (Addition & Subtraction Only)

setConfig({
  OPERATIONS: ['+', '-'],
  NUMBER_RANGE: { min: 1, max: 20 },
  AVOID_NEGATIVE_RESULTS: true
});

Hard Mode (Larger Numbers & Division)

setConfig({
  NUMBER_RANGE: { min: 10, max: 100 },
  DIVISION_PRECISION: 3,
  OPERATIONS: ['+', '-', '*', '/']
});

Kid-Friendly Mode

setConfig({
  OPERATIONS: ['+'],
  NUMBER_RANGE: { min: 1, max: 10 },
  AVOID_NEGATIVE_RESULTS: true
});

🔧 Framework Integration

Express.js

app.use(session({ secret: 'your-secret' }));

app.get('/captcha', (req, res) => {
  const question = generateRandomMathQuestion();
  req.session.captcha = question;
  res.render('form', { question: question.question });
});

React/Next.js

const [captcha, setCaptcha] = useState(null);

useEffect(() => {
  // Generate question on component mount
  const question = generateRandomMathQuestion();
  setCaptcha(question);
}, []);

const handleSubmit = (userAnswer) => {
  if (validateAnswerFlexible(captcha, userAnswer)) {
    // Success!
  }
};

Vue.js

data() {
  return {
    captcha: null,
    userAnswer: ''
  }
},
created() {
  this.captcha = generateRandomMathQuestion();
},
methods: {
  checkAnswer() {
    return validateAnswer(this.captcha, this.userAnswer);
  }
}

🧪 Testing

We've included comprehensive tests to ensure everything works perfectly:

npm test

The test suite includes:

  • ✅ 100+ test cases covering all scenarios
  • ✅ Edge case handling (malformed input, large numbers, etc.)
  • ✅ Performance tests (1000+ rapid generations)
  • ✅ Backward compatibility verification
  • ✅ All validation modes tested

🤝 Contributing

We love contributions! Here's how you can help:

  1. 🐛 Report Issues: Found a bug? Let us know!
  2. 💡 Suggest Features: Have ideas? We'd love to hear them!
  3. 🔧 Submit PRs: Code improvements are always welcome!
  4. 📖 Improve Docs: Help make this README even better!

Development Setup

git clone https://github.com/coffeeandfun/maths-captcha
cd maths-captcha
npm install
npm test

📄 License

This project is licensed under the MIT License. Feel free to use it in your projects!


🙏 Credits

Coffee & Fun LLC - Making the web more accessible and enjoyable


📞 Support

Need help? We're here for you!


🌟 Show Your Support

If this project helped you, consider:

  • ⭐ Starring the repository
  • 🐦 Sharing it with others
  • 💝 Contributing to make it even better

🧡 License

MIT – because sharing is caring.