npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@verifner/react-native

v0.1.0-alpha.0

Published

VerifNer React Native SDK: guided document and selfie capture for Nigerien identity verification

Readme

@verifner/react-native

Alpha (0.1.0-alpha.0). The API may change before 0.1.0; see What the alpha does not do yet.

Guided identity capture for the VerifNer verification API in a React Native app: document front (and back for a CNI), selfie, live quality gates, compression for 3G, upload with a short-lived client token. The React Native counterpart of @verifner/web: same session flow, same screens, same French and English copy.

How it works

  1. Your server calls POST /v1/sessions with the secret key and gets { id, client_token } (15 minutes, single use).
  2. Your app renders <VerifNerFlow> with those two values. The secret key never reaches the phone.
  3. The SDK uploads to POST /v1/sessions/:id/verify and calls onComplete.
  4. Your server decides from the verification.completed webhook or GET /v1/sessions/:id, never from the app: a result shown in the app can be tampered with.

Install

npm install @verifner/react-native \
  react-native-svg @react-native-community/image-editor \
  react-native-vision-camera@^4.6
cd ios && pod install

| Peer dependency | Why | |---|---| | react-native ≥ 0.74, react ≥ 18.2 | | | react-native-svg ≥ 15 | Icons and illustrations | | @react-native-community/image-editor ≥ 4.2 | Crop to the guide, resize to 1600 px, JPEG at about 300 KB | | react-native-vision-camera ^4.6 | The default camera. Optional: any camera library fits behind a small adapter |

Camera permission:

  • iOS, Info.plist: NSCameraUsageDescription, e.g. « VerifNer utilise la caméra pour photographier votre pièce d'identité et prendre un selfie. »
  • Android, AndroidManifest.xml: <uses-permission android:name="android.permission.CAMERA" />

1. Open a session on your server

app.post('/kyc/session', async (req, res) => {
  const r = await fetch('https://api.verifner.com/v1/sessions', {
    method: 'POST',
    headers: { Authorization: `Bearer ${process.env.VERIFNER_API_KEY}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ reference: req.user.id }), // document_type: 'cni' | 'passport' is optional
  });
  const s = await r.json();
  res.json({ sessionId: s.id, clientToken: s.client_token });
});

2. Render the flow

import { VerifNerFlow } from '@verifner/react-native';
import { visionCamera } from '@verifner/react-native/vision-camera';

<SafeAreaView style={{ flex: 1 }}>
  <VerifNerFlow
    sessionId={sessionId}
    clientToken={clientToken}
    apiUrl="https://api.verifner.com"
    camera={visionCamera}
    lang="fr"
    onComplete={(result) => navigation.replace('KycThanks')}
    onError={(e) => console.warn(e.code)}
    onExit={() => navigation.goBack()}
  />
</SafeAreaView>

example/App.tsx is a whole integration on one screen, and example/server.mjs the stand-in for your server (VERIFNER_API_KEY=vn_test_… node example/server.mjs).

Props

| Prop | Type | Default | Description | |---|---|---|---| | sessionId | string | required | The session id | | clientToken | string | required | The session client_token | | apiUrl | string | required | https://api.verifner.com | | camera | CameraAdapter | required | visionCamera, or your own | | lang | fr or en | fr | The welcome screen also has a switch | | documentType | cni or passport | | Skips the document picker | | selfie | boolean | true | Ask for a selfie | | theme | light, dark or auto | auto | auto follows the phone | | fontFamily | string | system font | A font registered in your app | | branding | object | the application's | Colour, logo, button shape, theme, texts. Normally set in the console (Personnalisation) and sent with the session; this prop replaces it. Entreprise plan | | autoCapture | boolean | false | Document photos take themselves once sharp and steady. By default the person taps a shutter that lights up when the view is right | | precheck | boolean | true | On "Vérifiez la photo", VerifNer's vision model says what to fix (wrong side, cut off, glare…). Advice only, never blocking | | showVerdict | boolean | false | Show the verdict (verified, in review, not confirmed), never its reasons. By default: "Vérification envoyée" | | pickImage | () => Promise<ImageFile \| null> | | Offer the gallery for document photos (never the selfie) | | onComplete | (result) => void | | { id, verdict, score, document_type, latency_ms, created_at } | | onError | ({ code, message }) => void | | An error shown to the person | | onStep | (step) => void | | intro, document, prepare, front, back, selfie, review, uploading, result, error | | onExit | () => void | | Adds a close button on the last screen and on errors, and handles Android's back on the first screen | | style | ViewStyle | | Style of the root view |

The flow fills its parent (flex: 1). Wrap it in a safe area.

Gallery

import { launchImageLibrary } from 'react-native-image-picker';

<VerifNerFlow
  {...}
  pickImage={async () => {
    const r = await launchImageLibrary({ mediaType: 'photo', selectionLimit: 1 });
    const a = r.assets?.[0];
    return a?.uri && a.width && a.height ? { uri: a.uri, width: a.width, height: a.height } : null;
  }}
/>

Errors shown in the app

| code | Cause | What the person sees | |---|---|---| | unreadable, not_an_image, extraction_failed | Photo too blurred or unreadable (422) | A button to retake. The session stays usable | | session_expired, session_completed, session_invalid | Session older than its TTL, already used, or bad token | Start again: open a new session | | insufficient_balance | Live key, the prepaid wallet is empty (402) | Try later | | network | No connection after three tries | A button to send again (the same photos) | | camera_denied, camera_unavailable | No permission or no camera | Retry, and a button to the phone's settings | | capture_failed, file_unreadable | The photo could not be taken or the picked file read | Retry |

Headless use

The API client works without the UI:

import { createClient } from '@verifner/react-native';

const vn = createClient({ apiUrl, sessionId, clientToken });
const session = await vn.session();                        // mode, status, branding, training
const issue = await vn.precheck(frontUri, 'cni', 'front'); // 'ok', an issue, or null
const out = await vn.verify({ front, back, selfie }, { onProgress: (f) => {} });
if (out.ok) out.result.verdict; else out.error.code;

verify retries 5xx answers and dropped connections (1 s, 2 s; three tries in all) and never retries a 4xx. prepareUpload(image, { stage, guide }) crops, resizes and compresses a photo the same way the flow does.

Another camera library

camera takes any object with this shape (CameraAdapter):

interface CameraAdapter {
  requestPermission(): Promise<boolean>;
  // forwardRef component; fill `style` with the preview in "cover" mode
  View: ComponentType<{ facing: 'back' | 'front'; active: boolean; style; onReady?(); onError?(code) } & RefAttributes<CameraHandle>>;
}
interface CameraHandle {
  takePhoto(): Promise<{ uri; width; height }>;    // size as displayed (EXIF applied)
  takeSnapshot?(): Promise<{ uri; width; height }>; // low-res preview frame; enables the live quality gate
}

src/adapters/vision-camera.tsx is the reference (about 60 lines). Without takeSnapshot the shutter is simply always available.

What the SDK does for you

  • Live quality gate, a few times a second: the region under the guide is scored for sharpness (Laplacian variance), glare and darkness with the same thresholds as the web SDK and the API's blur gate. The shutter lights up green when the view is clean and steady; it works anyway after 8 s, so no phone is ever blocked.
  • Photo check on the review screen: VerifNer's vision model says what is wrong (« C'est le verso : photographiez le recto »). About 2 s, never blocking, not stored or billed.
  • Crop to the guide with a small margin, resize to 1600 px on the long edge, JPEG stepped down from 0.85 to 0.6 until it fits about 300 KB.
  • Retries on bad networks, with progress while uploading.
  • Android back walks back through the screens.

What the alpha does not do yet

Compared with @verifner/web 0.5:

  • No face detection on the selfie (the web's pico.js « Rapprochez-vous », « Une seule personne » hints). The selfie is checked for light and sharpness only; the API still compares faces.
  • No Satoshi by default: the system font, or fontFamily.
  • No console preview mode (preview).
  • Live quality uses preview snapshots (takeSnapshot), which costs more battery than frame processors and writes temporary files the OS clears. A frame-processor path is planned.
  • Not yet validated on a range of devices: the crop of documents to the guide depends on each camera's reported orientation; please report a device where the cropped photo is off.
  • Only react-native-vision-camera 4 ships an adapter (5 is a different API); Expo Camera can be wrapped with the adapter interface above.

Contributing

See CONTRIBUTING.md for the development workflow and CODE_OF_CONDUCT.md for how we work together. Report security issues privately, as described in SECURITY.md. Never put a key, a client token, an identifier or a real identity document in an issue or a pull request.

npm install
npm run typecheck
npm run lint
npm test            # Jest: quality gates, crop geometry, flow, client, pixels, theme
npm run build       # lib/module + lib/typescript (react-native-builder-bob)

Pre-releases are published under the next dist-tag: npm install @verifner/react-native@next.

Licence

MIT.