New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@behindmycodes/react-native-caps

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@behindmycodes/react-native-caps

React Native integration for Cap widget and invisible solver via WebView

latest
Source
npmnpm
Version
0.1.6
Version published
Maintainers
1
Created
Source

react-native-caps

A small React Native helper library that integrates Cap in native apps via a WebView.

It wraps the browser-based @cap.js/widget (web component + WASM) so you can plug it into React Native with minimal configuration. Includes both a visible widget and an invisible solver.

Features

  • Visible widget using <cap-widget> rendered inside a WebView
  • Invisible mode using new Cap({ apiEndpoint }).solve()
  • Event bridge for solve, error, reset, progress
  • i18n attribute support and customizable CSS variables
  • Optional custom fetch and customizable WASM URL
  • WebView loading callbacks: start, end, progress, and load error
  • Optional ability to hide the widget attribution link

Requirements

  • React Native >= 0.74
  • React >= 18
  • react-native-webview installed in the app
  • A server exposing the Cap API at your chosen apiEndpoint

Install

Install from npm:

npm i @behindmycodes/react-native-caps react-native-webview
# or
yarn add @behindmycodes/react-native-caps react-native-webview

Usage

Import the components and provide your Cap API endpoint. The device must be able to reach this URL.

import { CapsWidget, CapsInvisible } from '@behindmycodes/react-native-caps';

// Visible widget
<CapsWidget
  apiEndpoint="http://192.168.1.10:3000/api/cap"
  onSolve={(token) => console.log('CAP token', token)}
  onError={(msg) => console.log('CAP error', msg)}
  onWebViewLoadStart={() => console.log('WebView loading started')}
  onWebViewLoadProgress={(p) => console.log('WebView loading progress', p)}
  onWebViewLoadEnd={() => console.log('WebView loading ended')}
  onWebViewError={(msg) => console.log('WebView load error', msg)}
  hideAttribution
  i18n={{ verifyingLabel: 'Verifying...', initialState: "I'm a human" }}
  cssVars={{ 'cap-widget-width': '260px', 'cap-widget-height': '60px' }}
  workerCount={8}
/>

// Invisible mode
<CapsInvisible
  apiEndpoint="http://192.168.1.10:3000/api/cap"
  onSolved={(token) => console.log('CAP token', token)}
  onError={(msg) => console.log('CAP error', msg)}
  onWebViewLoadStart={() => console.log('WebView loading started')}
  onWebViewLoadProgress={(p) => console.log('WebView loading progress', p)}
  onWebViewLoadEnd={() => console.log('WebView loading ended')}
  onWebViewError={(msg) => console.log('WebView load error', msg)}
/>

API

CapsWidget

Renders the Cap widget inside a WebView and bridges its events back to React Native.

Props:

  • apiEndpoint: string — your Cap API base URL
  • onSolve?: (token: string) => void — called when a token is generated
  • onError?: (message: string) => void — called on widget error
  • onReset?: () => void — called when the widget resets
  • onProgress?: (detail: unknown) => void — progress updates during verification
  • onWebViewLoadStart?: () => void — WebView started loading
  • onWebViewLoadEnd?: () => void — WebView finished loading
  • onWebViewLoadProgress?: (progress: number) => void — WebView load progress 0..1
  • onWebViewError?: (message: string) => void — WebView load error message
  • hideAttribution?: boolean — hides the widget attribution using ::part(attribution)
  • i18n?: Partial<{ verifyingLabel; initialState; solvedLabel; errorLabel; wasmDisabled; verifyAriaLabel; verifyingAriaLabel; verifiedAriaLabel; errorAriaLabel }> — maps to data-cap-i18n-* and ARIA attrs
  • cssVars?: Record<string, string> — sets CSS variables on the cap-widget element (keys should be the tail of --cap-*, e.g. { 'cap-background': '#fff' })
  • workerCount?: number — sets data-cap-worker-count
  • wasmUrl?: string — custom WASM JS loader URL
  • originWhitelist?: string[] — forwarded to WebView originWhitelist
  • customFetch?: boolean — if true, sets window.CAP_CUSTOM_FETCH = (url, opts) => fetch(url, opts) inside the WebView

CapsInvisible

Loads the Cap widget script as an ES module and triggers solve() immediately. No UI.

Props:

  • apiEndpoint: string
  • onSolved: (token: string) => void
  • onError?: (message: string) => void
  • onWebViewLoadStart?: () => void
  • onWebViewLoadEnd?: () => void
  • onWebViewLoadProgress?: (progress: number) => void
  • onWebViewError?: (message: string) => void
  • wasmUrl?: string
  • originWhitelist?: string[]
  • customFetch?: boolean

Customization

i18n

Set any of the supported attributes on the widget via the i18n prop (they map to data-cap-i18n-* and ARIA attributes):

<CapsWidget
  apiEndpoint="/api/cap"
  i18n={{
    verifyingLabel: 'Verifying...',
    initialState: "I'm a human",
    solvedLabel: "I'm a human",
    errorLabel: 'Error',
    wasmDisabled: 'Enable WASM for significantly faster solving',
  }}
/>

Styling via CSS variables

You can restyle the widget by providing cssVars. Example keys (correspond to --cap-*):

  • cap-background
  • cap-border-color
  • cap-border-radius
  • cap-widget-height
  • cap-widget-width
  • cap-widget-padding
  • cap-font
  • cap-spinner-color
<CapsWidget
  apiEndpoint="/api/cap"
  cssVars={{
    'cap-background': '#fdfdfd',
    'cap-widget-height': '60px',
    'cap-widget-width': '260px',
    'cap-font': 'system, -apple-system, Roboto, Segoe UI, sans-serif',
  }}
/>

Custom fetch

Override the widget’s network calls by enabling customFetch. This sets window.CAP_CUSTOM_FETCH inside the WebView:

<CapsWidget apiEndpoint="/api/cap" customFetch />

If you need more control, modify the implementation to inject your own function that adds headers or handles auth.

WASM URL

You can override the default WASM loader URL via wasmUrl. By default, it uses:

https://cdn.jsdelivr.net/npm/@cap.js/wasm@0.0.4/browser/cap_wasm.min.js

Host your own file if needed and pass its URL.

Server Requirements

Your server must implement the Cap API and be reachable from the device. If you rely on cookies or auth, ensure the WebView has appropriate session state and headers.

Notes

  • WebView is required because @cap.js/widget is a web component that relies on DOM and WebAssembly.
  • On React Native Web (web target), you can use the widget directly without WebView.

Publishing (maintainers)

  • Ensure you have rights to publish under the @behindmycodes org.
  • Bump the version in packages/react-native-caps/package.json following semver.
  • Publish:
cd packages/react-native-caps
npm publish --access public

If your npm account has 2FA for publishing, use --otp <code> or set an NPM_TOKEN in a local .npmrc:

//registry.npmjs.org/:_authToken=${NPM_TOKEN}

Repository: https://github.com/chief-fanatic/react-native-caps

Troubleshooting

  • import/no-unresolved for react-native-webview: install it in the app; it’s a peer dependency.
  • Token not received: ensure apiEndpoint is correct and reachable from the device (use an absolute IP on LAN).
  • Slow solving / warnings about WASM: confirm the WASM URL is reachable and not blocked by CSP or network.

Source

  • CapsWidget: packages/react-native-caps/src/widget/CapsWidget.tsx:1
  • CapsInvisible: packages/react-native-caps/src/widget/CapsInvisible.tsx:1
  • Types: packages/react-native-caps/src/widget/types.ts:1

License

MIT

Keywords

react-native

FAQs

Package last updated on 13 Nov 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts