An unofficial, open-source mobile client for Bitwarden-compatible password managers (including Vaultwarden), built with React Native and Expo.
This project is not affiliated with, endorsed by, or sponsored by Bitwarden, Inc.
Warning
Openwarden is an early-stage prototype. It is not feature-complete and is not ready for production use. Do not use it as your only client for sensitive credentials. Use the official Bitwarden mobile apps if you need a stable client for everyday use.
Openwarden is an independent, community-driven FOSS mobile client for the Bitwarden API. The goal is a native, modern, fast password manager that works against any Bitwarden-compatible server β the official cloud, or a self-hosted Bitwarden instance such as Vaultwarden β without depending on the official mobile codebase.
Mobile (iOS and Android) is the starting point. Desktop and browser extension clients are planned for the future.
Openwarden is an early prototype. The tables below are the rough scope a "feature-complete" Bitwarden mobile client implies plus some additional features Openwarden plans to implement in addition to the official Bitwarden mobile apps. Items already implemented are marked with β .
| Feature | Status |
|---|---|
| Login with email + master password | β |
| PBKDF2-SHA256 and Argon2id KDFs | β |
| OAuth refresh-token rotation | β |
| Logout | β |
| Account creation / signup | |
| Forgot password / master password hint retrieval | |
| Two-factor login via OTP | β |
| Two-factor login via email verification code | β |
| Two-factor login via WebAuthn | β |
| Two-factor login via Duo | β |
| Two-factor login via YubiKey USB-C (HID) / NFC | β |
| SSO login | |
| Login with device (passwordless / approve-from-other-device) | |
| Multi-account support |
| Feature | Status |
|---|---|
| Master password unlock | β |
| Biometric unlock (Face ID / Touch ID / Android biometrics) | β |
| PIN unlock | |
| Manual "Lock vault" from settings | β |
| Auto-hide revealed secrets after inactivity | β |
| Vault timeout (auto-lock after N minutes of inactivity or on backgrounding) | β |
Master password reprompt on reveal/copy (honoring cipher.reprompt) |
| Feature | Status |
|---|---|
| Full vault sync on login | β |
| Incremental / revision-based sync | β |
| Pull-to-refresh | β |
| Push local changes back to the server | |
| Real-time push notifications | |
| Organization & collection ciphers |
| Feature | Status |
|---|---|
| List personal-account ciphers | β |
| "Favorites" section | β |
| Favicon with cipher-type fallback icon | β |
| Search | β |
| Filters | |
| Folder support | |
| Collection browsing | |
| Trash / restore / permanently delete | |
| Bulk actions |
| Feature | Status |
|---|---|
| Login | β |
| Secure note | β |
| Custom fields: text and hidden | β |
| Custom fields: boolean and linked | |
| Card | β |
| Identity | β |
| SSH Key |
| Feature | Status |
|---|---|
| Username and password | β |
| Secure note body | β |
| "Open" link | β |
| Created / modified metadata | β |
| Copy to clipboard | β |
| TOTP / authenticator codes | |
| Password history / password revision date | |
| Attachments (download / preview) | |
| All URIs with match-detection rules |
| Feature | Status |
|---|---|
| Create new item | |
| Edit existing item | |
| Delete to trash / restore / permanently delete | |
| Favorite toggle | |
| Move to folder | |
| Folder CRUD | |
| Clone item | |
| Attachment upload / management | |
| Share to organization / collection |
| Feature | Status |
|---|---|
| Password generator | β |
| Passphrase generator | β |
| Username generator | β |
| Generator history |
| Feature | Status |
|---|---|
| Create text Send | |
| Create file Send | |
| View / edit / delete Sends | |
| Share Send links |
| Feature | Status |
|---|---|
| iOS AutoFill credential provider extension | |
| Android Autofill framework integration | |
| Android Accessibility Service autofill | |
| Passkey (FIDO2 / WebAuthn) storage and use | |
| QuickType bar suggestions (iOS) | |
| Per-URI match detection settings |
| Feature | Status |
|---|---|
| View profile data | |
| Change master password | |
| Change email | |
| Change KDF type / iterations | |
| Manage two-step login methods | |
| Personal API key | |
| Export vault (encrypted / unencrypted JSON or CSV) | |
| Import vault | |
| Emergency Access | |
| Delete account | |
| Trusted devices |
| Feature | Status |
|---|---|
| Browse organization ciphers | |
| Collections | |
| Organization-level permissions / events |
| Feature | Status |
|---|---|
| Encrypted local SQLite (SQLCipher) | β |
| In-memory decryption cache | β |
| Prevent screenshots | β |
| Obscure app contents in the app switcher | β |
| "Show website icons" toggle | |
| Breach reports / data-breach notifications and password health reports |
| Feature | Status |
|---|---|
| Bottom-tab navigation | β |
| Dark Mode | β |
| Theme override in settings | β |
| Localization / additional app languages | |
| Onboarding flow | |
| About / version / open-source attribution screen | |
| In-app help & feedback | |
| Push notifications (new-device login, vault changes) |
Non-exhaustive list of the most important libraries and frameworks:
- Expo (React Native)
- TypeScript
- React Navigation
- TanStack Query for server state, Zustand for client state
- Drizzle ORM over
op-sqlitewith SQLCipher for the encrypted local vault react-native-quick-cryptofor cryptographic primitives (PBKDF2, Argon2id, AES-CBC/GCM, HMAC, HKDF)expo-secure-store(Keychain / Keystore) for storage of sensitive data- Unistyles for theming
openapi-typescript+openapi-fetchfor a typed Bitwarden API client
Openwarden tries to follow at least the same cryptographic model as the official Bitwarden clients:
- The master password never leaves the device. It is used to derive the master key via the KDF advertised by the server (PBKDF2-SHA256 or Argon2id).
- The master key decrypts the account key (the symmetric vault key) returned by the server. All cipher strings stored in the local database remain encrypted with the account key and are only decrypted in memory while the vault is unlocked.
- Biometric unlock works by wrapping the account key with a random AES-256-GCM key stored behind biometric authentication in the platform secure storage (iOS Keychain, Android Keystore).
- The local vault database is opened with a per-account random SQLCipher key kept in secure storage.
- An in-memory decryption cache for cipher strings is cleared whenever the vault locks.
- Node.js (ideally using
nvmwith the version pinned in.nvmrc) - pnpm (ideally using
corepackwith the version specified inpackage.json'spackageManagerfield) - Xcode (for iOS) and/or Android Studio (for Android), with a configured simulator/emulator or a connected device
- CocoaPods for iOS
Openwarden uses native modules (react-native-quick-crypto, op-sqlite with SQLCipher, expo-secure-store, react-native-bottom-tabs, etc.) and therefore cannot run in Expo Go. You must use the development build flow.
pnpm installpnpm iospnpm androidThe first run builds the native dev client; subsequent runs only restart Metro.
On the login screen, enter the URL of your Bitwarden-compatible server (for example https://vault.bitwarden.com, or your Vaultwarden instance), your account email, and master password. Openwarden currently expects an account already exists on the target server.
src/
βββ api/ Typed Bitwarden API client (generated from OpenAPI) + services
βββ app/ App entry, providers, navigation root
βββ components/ Shared UI primitives
βββ crypto/ Bitwarden cryptographic primitives (e.g. KDF, cipher strings, account key)
β βββ bitwarden/ Direct Bitwarden-compatibility code (e.g. PBKDF2/Argon2id, AES, HMAC, HKDF)
βββ features/ Larger domain features with hooks/services/state
βββ hooks/ Generic React hooks
βββ screens/ Top-level screens
βββ styles/ Unistyles theme and design tokens
βββ types/ Shared TypeScript types
βββ utils/ Generic utilities
| Command | What it does |
|---|---|
pnpm start |
Start the Expo dev server / Metro |
pnpm ios |
Build and run the iOS dev client |
pnpm android |
Build and run the Android dev client |
pnpm test |
Run the Vitest unit test suite |
pnpm typecheck |
Run the TypeScript compiler in --noEmit mode |
pnpm lint / pnpm lint:fix |
Run ESLint (read-only / autofix) |
pnpm format / pnpm format:fix |
Run Prettier (check / write) |
pnpm quality / pnpm quality:fix |
Typecheck + lint + format |
pnpm generate:api |
Regenerate the typed Bitwarden API client from the OpenAPI spec |
pnpm generate:db |
Regenerate Drizzle migrations from the schema |
CI runs lint, format, typecheck, tests and a generated-files drift check on every pull request β see .github/workflows/lint.yml.
Contributions are welcome. Please read CONTRIBUTING.md before opening an issue or pull request. In short:
- Open issues for bugs and feature requests; check existing issues first.
- Open pull requests against
main. - AI-assisted contributions are allowed but must be disclosed, reviewed by you, and held to the same quality bar as any other contribution.
If you discover a security vulnerability, please do not open a public issue and disclose it responsibly. Report it privately by emailing the maintainer or using GitHub's private vulnerability reporting on the repository.
Openwarden is released under the GNU General Public License v3.0.
- Bitwarden for the open password-manager protocol and reference implementation.
- The Rubywarden API documentation, which has been invaluable for understanding the Bitwarden login and sync flows.