LogoBetter Captcha

Getting Started

Install, configure, and extend better-captcha for production-ready CAPTCHA integrations.

This library is in early development and is not production ready yet. Expect breaking API changes while the provider surface stabilizes.

Overview

better-captcha provides a unified, framework-agnostic interface for popular CAPTCHA providers. Each widget ships as a client component that:

  • ✅ Loads provider scripts safely on demand
  • ✅ Exposes a predictable imperative handle
  • ✅ Makes tokens easy to retrieve during form submissions
  • ✅ Shares the same lifecycle across all providers
  • ✅ Allows you to swap vendors without touching your UI

Quick Start

1. Install the package for your framework

FrameworkPackageInstallation
React@better-captcha/reactnpm i @better-captcha/react
Qwik@better-captcha/qwiknpm i @better-captcha/qwik
SolidJS@better-captcha/solidjsnpm i @better-captcha/solidjs
Vue@better-captcha/vuenpm i @better-captcha/vue
Svelte@better-captcha/sveltenpm i @better-captcha/svelte
Lit@better-captcha/litnpm i @better-captcha/lit

2. Import and use a provider

import { ReCaptcha } from "@better-captcha/react/provider/recaptcha";

export function ContactForm() {
  return <ReCaptcha sitekey="your-site-key" />;
}

3. Access the handle to control the widget

import { useRef } from "react";
import { ReCaptcha, type ReCaptchaHandle } from "@better-captcha/react/provider/recaptcha";

export function ContactForm() {
  const captchaRef = useRef<ReCaptchaHandle>(null);

  const handleSubmit = async () => {
    const token = captchaRef.current?.getResponse();
    // Send token to your backend for verification
  };

  return (
    <form onSubmit={handleSubmit}>
      <ReCaptcha ref={captchaRef} sitekey="your-site-key" />
      <button type="submit">Submit</button>
    </form>
  );
}

Supported Providers

ProviderDescriptionAuto Theme
ReCaptchaGoogle's comprehensive bot protectionEnhanced ✨
hCaptchaPrivacy-focused with monetizationEnhanced ✨
TurnstileCloudflare's privacy-first alternativeNative ✅
Friendly CaptchaGDPR-compliant, no user interactionNative ✅
Private CaptchaSelf-hosted with full controlEnhanced ✨
Captcha FoxCustomizable themes and challengesEnhanced ✨
ProsopoWeb3-integrated bot protectionEnhanced ✨
CapWidgetCap.JS widget libraryN/A

Key Features

Unified API

All providers share the same imperative handle methods:

  • render() - Render the CAPTCHA widget
  • execute() - Trigger the CAPTCHA challenge
  • reset() - Reset the widget to its initial state
  • destroy() - Clean up and remove the widget
  • getResponse() - Get the current response token

Lifecycle Callbacks

Every provider supports three lifecycle callbacks:

  • onReady - Called when the widget is rendered and ready
  • onSolve - Called when the challenge is solved with a token
  • onError - Called when an error occurs

Framework-Specific Integration

Each framework has its own idiomatic way of accessing the handle:

  • React: useRef hook
  • Qwik: useCaptchaController hook
  • SolidJS: createCaptchaController function
  • Vue: useCaptcha composable or template refs
  • Svelte: bind:this directive
  • Lit: getHandle() method

Next Steps

On this page