Skip to main content

Mobile & frontend apps

The SDK is isomorphic — it runs in browsers, edge runtimes, Deno, and Bun, not just Node. But for React, Flutter, or any mobile/SPA app, the question isn’t “does it run?” — it’s “where should it run?” Rule: the API key never ships in a client app. Anything bundled into JavaScript or a mobile binary is public — anyone can extract a bsk_ key from a JS bundle or a decompiled APK and use it against your account. So the architecture is the same for every frontend framework:
Your frontend needs zero Blursec code. The credential check lives in front of /login on your server — see examples/login-endpoint.ts. That’s by design: it keeps the key secret and keeps the 1500 ms fail-open latency budget where it belongs.

React / Vue / SPA (web)

For login, do nothing special — the form posts to your backend as usual and the server runs credentials.check. There is one pattern where client-side SDK code genuinely helps: pre-hash screening. The hash helpers (hashCredential, hashString) work in any modern browser via crypto.subtle, so a signup or password-change form can:
  1. Hash email:password locally with hashCredential().
  2. Send only the 64-char digest to your backend.
  3. Your backend calls credentials.checkHash(digest) — and Blursec still only ever sees the first 10 characters.
The plaintext password never leaves the page, never appears in your server logs, and never reaches Blursec. Full working example: examples/react-prehash.tsx. Caveats:
  • crypto.subtle requires a secure context (HTTPS or localhost).
  • This is for screening (signup, password change, security checkups). For login your server needs the password anyway to verify it against your own store — hash server-side there.
  • Never call the Blursec API directly from the browser, even with hashes — that requires shipping the key. Always proxy through your backend. See examples/browser.ts for the longer sermon.

React Native / Expo

Two extra wrinkles:
  • No crypto.subtle. Hermes does not implement WebCrypto, so hashCredential() throws. Either polyfill it (react-native-quick-crypto exposes a compatible subtle, inject it before importing the SDK) or — simpler and recommended — don’t hash on the device at all and let your backend do everything.
  • Same key rule. A key in an .ipa/.apk is public. Proxy through your backend.
The recommended React Native integration is therefore identical to web: post credentials to your own /login over TLS, check server-side.

Flutter, Swift, Kotlin, and everything else

There is no Dart/Swift/Kotlin SDK, and for the standard integration you don’t need one — the app talks to your backend, and your backend (Node, edge, or anything that can run this SDK) talks to Blursec. If you have a hard requirement to hash on-device (e.g. an offline-first password screener), the protocol is deliberately tiny and documented in Advanced usage:
  1. digest = SHA-256(lowercase(trim(email)) + ":" + password) as lowercase hex.
  2. Send the first 10 chars (HASH_PREFIX_LENGTH) to POST /v1/credentials/checkfrom your backend, which holds the key.
  3. Compare the returned suffixes against your local digest.
Every platform above has a native SHA-256 (CryptoKit, crypto in Dart, MessageDigest in Kotlin), so step 1 is a few lines anywhere.

Decision table