Build your own GIF-based CAPTCHA system in minutes
GIF CAPTCHA is a human-verification system that uses animated GIFs with narrative twists. Users must describe what happened in a GIF โ something trivially easy for humans who can watch the animation, but impossible for text-based AI models that can't process animated content.
๐ก Key insight: In testing, GPT-4 scored 0/10 on GIF CAPTCHAs because it fundamentally cannot view animated images. Even vision-capable models struggle with temporal comprehension of unexpected events.
npm install gif-captcha
Or include directly via CDN:
<script src="https://unpkg.com/gif-captcha/src/index.js"></script>
const gifCaptcha = require("gif-captcha");
const challenges = [
gifCaptcha.createChallenge({
id: 1,
title: "Cat vs Cucumber",
gifUrl: "https://example.com/cat-cucumber.gif",
humanAnswer: "The cat jumped when it saw the cucumber behind it",
keywords: ["cat", "jumped", "cucumber"]
}),
gifCaptcha.createChallenge({
id: 2,
title: "Plot Twist Duel",
gifUrl: "https://example.com/duel-twist.gif",
humanAnswer: "Both duelists fired trick guns with flags",
keywords: ["trick", "guns", "flags"]
}),
// ... add more challenges
];
// Pick 5 random challenges for this session
const selected = gifCaptcha.pickChallenges(challenges, 5);
// For each challenge, show the GIF and collect user input
selected.forEach(challenge => {
const container = document.getElementById('captcha-' + challenge.id);
gifCaptcha.loadGifWithRetry(container, challenge);
});
// When user submits their answer:
function checkAnswer(challenge, userInput) {
const result = gifCaptcha.validateAnswer(
userInput,
challenge.humanAnswer,
{ threshold: 0.3, requiredKeywords: challenge.keywords }
);
if (result.passed) {
console.log("Human verified! Score:", result.score);
} else {
console.log("Verification failed. Score:", result.score);
}
}
For a complete browser-based implementation, check the interactive demo which shows the full flow: GIF display, user input, answer comparison, and scoring.
<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/gif-captcha/src/index.js"></script>
</head>
<body>
<div id="captcha-container"></div>
<input type="text" id="answer" placeholder="Describe what happened...">
<button onclick="verify()">Verify</button>
<script>
var challenge = gifCaptcha.createChallenge({
id: 1,
title: "Surprise",
gifUrl: "https://example.com/surprise.gif",
humanAnswer: "The box opened and confetti flew out"
});
gifCaptcha.loadGifWithRetry(
document.getElementById("captcha-container"),
challenge
);
function verify() {
var answer = document.getElementById("answer").value;
var result = gifCaptcha.validateAnswer(answer, challenge.humanAnswer);
alert(result.passed ? "Human! โ
" : "Bot? โ Score: " + result.score);
}
</script>
</body>
</html>
|A โฉ B| / |A โช B|{ passed, score, hasKeywords }๐ง Tuning the threshold: Lower values (0.2) are more forgiving, higher values (0.5) require closer matches. For CAPTCHAs, 0.3 works well โ it catches AI refusals ("I cannot view images") while allowing human variations ("the cat freaked out" vs "the cat jumped in surprise").
Effective GIF CAPTCHAs share these characteristics:
Use the CAPTCHA Workshop to build and test your own challenge sets.
GitHub ยท npm ยท Case Study ยท MIT License