๐Ÿš€ Getting Started

Build your own GIF-based CAPTCHA system in minutes

What is GIF CAPTCHA?

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.

Quick Start

1

Install

npm install gif-captcha

Or include directly via CDN:

<script src="https://unpkg.com/gif-captcha/src/index.js"></script>
2

Define Challenges

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
];
3

Present & Validate

// 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);
  }
}

Browser Integration

For a complete browser-based implementation, check the interactive demo which shows the full flow: GIF display, user input, answer comparison, and scoring.

Minimal HTML Example

<!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>

How Validation Works

  1. Tokenization โ€” Both the user's answer and expected answer are split into words and lowercased
  2. Jaccard Index โ€” Calculates word-level overlap: |A โˆฉ B| / |A โˆช B|
  3. Threshold Check โ€” Score must be โ‰ฅ threshold (default 0.3, i.e. 30% word overlap)
  4. Keyword Check โ€” If required keywords are specified, at least one must appear in the answer
  5. Result โ€” Returns { 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").

Creating Good Challenges

Effective GIF CAPTCHAs share these characteristics:

  1. Unexpected event โ€” Something surprising happens that requires watching the full animation
  2. Temporal dependency โ€” Understanding requires seeing events unfold over time
  3. Narrative surprise โ€” The "answer" can't be guessed from a single frame
  4. Unambiguous outcome โ€” Humans generally agree on what happened

Use the CAPTCHA Workshop to build and test your own challenge sets.

Next Steps


GitHub ยท npm ยท Case Study ยท MIT License