react-hcaptcha
Drop-in React and Preact components for adding hCaptcha bot-protection challenges to any form.
Repository Health
Technical Analysis
@hcaptcha/react-hcaptcha wraps hCaptcha’s client-side verification widget in a single React component, handling script injection, iframe/window resolution, and full lifecycle management (mount, reset, remove, and React 18 Strict Mode safety) so consumers don’t have to touch the underlying global hcaptcha object directly. It ships both an imperative <HCaptcha ref> API matching hCaptcha’s native JS methods (execute, resetCaptcha, getResponse, setData) and a declarative HCaptchaProvider/useHCaptcha hook pair for teams that prefer context-driven state.
Built as a pnpm-workspace monorepo (lib + demo), the package compiles to dual ESM/CJS bundles via esbuild and is typed through hand-maintained .d.ts definitions, with peer dependencies on React and React DOM 16.8+. It supports hCaptcha Enterprise options (rqdata, custom hosts, Sentry integration) alongside the standard checkbox/invisible/passive challenge modes, making it usable from simple signup forms up to enterprise bot-mitigation deployments.
What You Get
- A drop-in <HCaptcha> component that injects the hCaptcha script, mounts the widget, and cleans it up automatically on unmount
- A declarative HCaptchaProvider + useHCaptcha() hook exposing ready/token/error state and an executeInstance() helper for invisible challenges
- Full support for hCaptcha’s imperative JS API - execute(), resetCaptcha(), getResponse(), getRespKey(), setData() - via a component ref
- Enterprise-ready configuration (rqdata, custom hosts, Sentry reporting, custom themes) for teams on hCaptcha Enterprise/BotStop
- TypeScript type definitions shipped alongside the package for both the class component and the hooks entrypoint
Common Use Cases
- Protecting signup and login forms from bot submissions with a standard checkbox challenge
- Adding an invisible hCaptcha challenge triggered programmatically on form submit via execute()
- Gating high-risk actions (password resets, checkout, comment posting) behind a captcha challenge with onVerify callbacks
- Integrating hCaptcha Enterprise features like passive risk scoring and custom rqdata payloads
Under The Hood
Architecture The library is a thin wrapper: a single class component (HCaptcha.jsx) wraps the global hcaptcha JS API loaded via the first-party @hcaptcha/loader package, injecting a script tag and reading the API off the window/iframe object (getFrame/getMountElement in utils.js multiplex between same-document and cross-frame mounting). A separate Context/Provider/hook layer (Context.tsx, Provider.tsx, useHCaptcha.tsx) wraps the class component to expose a declarative useHCaptcha() hook with ready/token state, itself delegating imperative calls (execute, resetCaptcha, setData) to a ref of the underlying class component. Data flow is callback-driven and one-directional: hCaptcha’s iframe invokes global callbacks configured at render time, which map to instance methods that call user-supplied props. Async imperative execution is handled by a pendingExecute/onReady pair that queues execute() calls until the API is ready, with explicit cancellation on unmount, reset, or replacement.
Tech Stack Mixed TypeScript/JavaScript (roughly two-thirds TS), targeting React and react-dom 16.8+ as peer dependencies, built with esbuild into dual ESM/CJS bundles, typed via hand-maintained ambient declaration files rather than compiler-emitted types. The sole runtime dependency is the project’s own @hcaptcha/loader package. Tests run on Jest with @testing-library/react and swc for fast TS/JSX transpilation. The repo is a pnpm-workspace monorepo separating the published library from a webpack-based demo app, with GitHub Actions running CI and CodeQL analysis on every push plus a dedicated publish workflow.
Code Quality Tests are substantive rather than superficial, covering the component, the loader-error path, and the hooks, built around a hand-rolled mock of the global hcaptcha API so widget behavior can be simulated without a live captcha. Error handling is explicit and defensive: unmount logic wraps hcaptcha.reset/remove in try/catch/finally specifically to survive React Strict Mode’s double-invoked effects, and the async execute() path branches deliberately between a resolved value, a rejected promise, and a cancelled pending call rather than swallowing failures silently. Type coverage is uneven, though - the core class component remains untyped JS while the hooks layer uses TypeScript - and there is no visible lint configuration in the repository.
API Design The library offers a two-tier API rare among third-party widget wrappers: a low-level imperative ref matching hCaptcha’s native JS methods one-to-one, and a higher-level Provider/hook pair for consumers who would rather read ready/token state from context than manage refs themselves. Getting started requires only a sitekey prop and an onVerify callback, while power users get Enterprise fields (rqdata, custom hosts, userJourneys) and promise-based async execute() with explicit cancellation. Documentation is thorough, with a full props/events/methods reference table and a dedicated debugging section covering common integration pitfalls.
Used by 3 apps in this directory
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
OneUptime
Monitoring
The complete open-source observability platform that replaces PagerDuty, Datadog, Sentry, and StatusPage with a single self-hostable system.
Supabase
Developer Tools · Databases · Search
The open-source Postgres development platform that replaces Firebase with authentication, real-time APIs, edge functions, storage, and vector embeddings — all built on PostgreSQL.