A modern, dynamic, multilingual math-based CAPTCHA widget for the web.
Live Demo & Documentation · Quick Start · Configuration · Security Notes
- Overview
- Features
- Interface Preview
- Important Security Disclaimer
- Requirements
- Quick Start
- Difficulty Levels
- Languages
- Themes
- Configuration
- Callback API
- Verification Flow
- Security Notes
- Privacy
- Terms of Use
- License
- Author and Maintainer
- Links
MathCAPTCHA is a lightweight, client-side CAPTCHA widget that uses dynamically generated mathematical challenges as a human-verification mechanism. Instead of image-based CAPTCHA challenges, it presents mathematical problems across multiple difficulty levels, from basic arithmetic to calculus.
Built with Vanilla JavaScript (ES6), MathCAPTCHA can be integrated into a standard HTML page without requiring a frontend framework.
Live Demo & Documentation: https://jproject-1.github.io/captcha-math/
- Dynamic mathematical challenges — generates questions dynamically and supports multiple categories of mathematical problems.
- 7 difficulty levels — spans basic arithmetic, roots and powers, algebra, trigonometry, probability and expectation, vectors, and calculus.
- Random difficulty — set
level: 'random'to choose a challenge from the available levels. - 9 interface languages — Indonesian, English, Spanish, Chinese, Japanese, Russian, French, Arabic, and Hindi.
- Automatic language detection —
auto-webdetects language from the browser/web environment;auto-usersupports user-oriented language detection according to the implementation logic. - Light and dark themes — supports
light,dark, andautomodes. - Vanilla JavaScript — no frontend framework is required.
- Callback API — receive events for successful verification, failed attempts, and client-side blocked states.
- Client-side verification token — a token may be returned after success for application-specific handling. It is not a cryptographically secure proof of verification.
Warning
MathCAPTCHA is intended for entertainment, educational purposes, experimentation, and lightweight human verification. It is not designed to provide strong protection against sophisticated bots or automated attacks.
Do not treat MathCAPTCHA alone as a complete security solution for large-scale websites, official services, banking or financial systems, authentication systems, administrative systems, high-value transactions, or systems requiring strong anti-bot protection.
A determined user may inspect, modify, or bypass client-side JavaScript. For stronger protection, combine it with server-side validation, rate limiting, authentication controls, abuse prevention, or a dedicated anti-bot service. The developer integrating MathCAPTCHA is responsible for determining whether it is appropriate for the application's threat model.
- HTML5
- JavaScript enabled
- A modern web browser
No frontend framework is required.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MathCAPTCHA Example</title>
</head>
<body>
<div id="my-captcha-box"></div>
<script src="https://jproject-1.github.io/captcha-math/api.js"></script>
<script>
const myCaptcha = new MathCAPTCHA({
containerId: 'my-captcha-box',
mode: 'auto',
language: 'id',
level: 'random',
maxAttempts: 5,
onSuccess: (response) => {
console.log('Verification successful:', response);
// Handle response.data.token according to your own application flow.
},
onFail: (response) => {
console.log('Verification failed:', response);
},
onBlocked: (response) => {
console.log('Maximum attempts reached:', response);
}
});
</script>
</body>
</html>The widget is rendered into the element whose ID is configured through containerId:
<div id="my-captcha-box"></div>Load api.js before creating the MathCAPTCHA instance. Use a valid container ID and choose the language, theme, difficulty, attempt limit, and callback functions appropriate to your page.
MathCAPTCHA provides 7 mathematical difficulty levels:
| Level | Category | Description |
|---|---|---|
1 |
Basic Arithmetic | Basic arithmetic operations. |
2 |
Roots & Powers | Problems involving roots and powers. |
3 |
Basic Algebra | Algebraic expressions and equations. |
4 |
Trigonometry | Trigonometric problems and calculations. |
5 |
Probability & Expectation | Probability and expected-value problems. |
6 |
Vectors | Vector problems involving dot products. |
7 |
Calculus | Calculus problems involving derivatives. |
random |
All Levels | Randomly selects a challenge from the available levels. |
Use a specific difficulty:
const captcha = new MathCAPTCHA({
containerId: 'my-captcha-box',
level: 4
});Or select randomly:
const captcha = new MathCAPTCHA({
containerId: 'my-captcha-box',
level: 'random'
});MathCAPTCHA currently supports 9 interface languages:
| Code | Language |
|---|---|
id |
Indonesian |
en |
English |
es |
Spanish |
zh |
Chinese |
ja |
Japanese |
ru |
Russian |
fr |
French |
ar |
Arabic |
hi |
Hindi |
const captcha = new MathCAPTCHA({
containerId: 'my-captcha-box',
language: 'id'
});The documented automatic modes are:
auto-webauto-user
These modes choose a suitable language according to the implementation's language-detection logic.
MathCAPTCHA supports three display modes:
| Mode | Description |
|---|---|
light |
Light theme. |
dark |
Dark theme. |
auto |
Automatically adapts to the user's preferred theme. |
Example:
const captcha = new MathCAPTCHA({
containerId: 'my-captcha-box',
mode: 'dark'
});Pass a configuration object to new MathCAPTCHA({...}).
| Parameter | Type | Default | Description |
|---|---|---|---|
containerId |
String |
null |
Required. ID of the HTML element where MathCAPTCHA will be rendered. |
mode |
String |
'auto' |
Display mode: 'light', 'dark', or 'auto'. |
language |
String |
'auto-web' |
Interface language: id, en, es, zh, ja, ru, fr, ar, hi, auto-web, or auto-user. |
level |
Integer | String |
'random' |
Difficulty from 1 to 7, or 'random'. |
maxAttempts |
Integer |
5 |
Maximum failed attempts before the current instance enters the blocked state. |
onSuccess |
Function |
— | Called when the user successfully solves the challenge. |
onFail |
Function |
— | Called on a failed attempt, including when the CAPTCHA is closed by the user. |
onBlocked |
Function |
— | Called when the maximum number of attempts is reached. |
MathCAPTCHA provides three primary callbacks: onSuccess, onFail, and onBlocked.
Called when the user solves the challenge successfully.
onSuccess: (response) => {
console.log('Success:', response);
}Example response:
{
"status": "success",
"data": {
"levelPlayed": 4,
"attemptsUsed": 2,
"timestamp": "2026-08-24T12:00:00.000Z",
"token": "..."
}
}The token returned by onSuccess is generated on the client side. It is based on encoded verification information (including values such as verification state, timestamp, and level) using btoa(...).
Conceptually:
verification state + timestamp + level
↓
btoa()
↓
token
Caution
Base64 encoding is not encryption and does not provide cryptographic authenticity by itself. Do not treat this token as a cryptographically secure proof of verification. If stronger protection is required, implement your own server-side validation and security mechanism.
Called when a verification attempt fails. This includes an incorrect answer and closing/cancelling the CAPTCHA.
onFail: (response) => {
console.log('Verification failed:', response);
}Example response:
{
"status": "failed",
"reason": "wrong_answer",
"attemptsUsed": 1,
"maxAttempts": 5,
"levelPlayed": 4,
"timestamp": "2026-08-24T12:00:00.000Z"
}Depending on the event, reason may indicate why verification failed, for example:
wrong_answer
closed_by_user
Called after the user reaches the configured maxAttempts limit.
onBlocked: (response) => {
console.log('CAPTCHA blocked:', response);
}Example response:
{
"status": "blocked",
"reason": "wrong_answer",
"attemptsUsed": 5,
"maxAttempts": 5,
"levelPlayed": 4,
"timestamp": "2026-08-24T12:00:00.000Z"
}The blocked state applies to the current client-side CAPTCHA instance. After the configured attempt limit is reached, the user must refresh the page to start that instance again. This does not permanently block the user from the website.
MathCAPTCHA itself does not provide account-level, IP-level, or server-side blocking. Persistent blocking must be implemented by the integrating application's backend.
CAPTCHA starts
|
v
Generate math challenge
|
v
User submits answer
|
+---+---+
| |
Wrong Correct
| |
v v
onFail() onSuccess()
|
v
Attempts remaining?
|
+------ No ------> onBlocked()
| |
Yes v
| Refresh page
v
Retry
MathCAPTCHA runs primarily on the client side. The JavaScript code, challenge generation, and verification process can potentially be inspected or modified by the user. It should therefore not be treated as a complete security boundary.
For security-sensitive applications, consider combining it with:
- Server-side validation
- Rate limiting and request throttling
- Authentication and session validation
- Abuse detection
- IP/device controls where appropriate
- A dedicated anti-bot service
Choose controls according to the application's requirements and threat model.
MathCAPTCHA itself does not intentionally collect, store, track, or share personal information such as IP addresses, user location, user profiles, browsing history, or personal identification information as part of its CAPTCHA functionality.
The website or application integrating MathCAPTCHA may independently collect data through its backend, hosting provider, analytics services, cookies, CDN, or other third-party services. Those services are outside the scope of MathCAPTCHA itself.
MathCAPTCHA generates mathematical challenges dynamically and validates the user's answer within the widget. The project does not intentionally send user activity logs to third-party analytics or marketing services as part of the CAPTCHA functionality.
MathCAPTCHA does not use tracking cookies, advertising cookies, localStorage, or sessionStorage for its CAPTCHA functionality. CAPTCHA state is handled by the application running in the browser and does not require persistent browser storage.
The hosted script may be loaded from:
https://jproject-1.github.io/captcha-math/
Consider the privacy policies and infrastructure of any external hosting or services used by the integrating application.
By using or integrating MathCAPTCHA, you acknowledge that:
- MathCAPTCHA is provided as open-source software.
- It is primarily intended for educational, experimental, entertainment, and lightweight verification purposes.
- It is not a complete anti-bot security solution.
- You are responsible for evaluating the software before deploying it.
- You are responsible for adding further security mechanisms when required.
- You are responsible for complying with applicable laws and regulations.
- You are responsible for the security and privacy practices of the application in which it is integrated.
MathCAPTCHA is released under the MIT License.
Copyright © 2026 Jasonpw
MIT License
Copyright (c) 2026 Jasonpw
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
- Author: Jasonpw
- Maintainer: YCYL STUDIO
- Live Demo & Documentation: https://jproject-1.github.io/captcha-math/
- Author: https://jasonpw.web.id/
- YCYL STUDIO: https://ycylstudio.web.id/
Issues, suggestions, and improvements are welcome through the project's available communication channels.

