Skip to main content
The Bitwarden Desktop app uses Rust native modules for platform-specific functionality and performance-critical operations. These modules are exposed to Node.js via N-API (Node API).

Overview

Native modules provide:
  • Platform integration: OS-specific features (biometrics, keychain, etc.)
  • Performance: Computation-heavy operations in Rust
  • Security: Memory-safe operations for sensitive data
  • Cross-platform consistency: Single Rust codebase with platform-specific implementations

Directory Structure

Core Modules

Biometric Authentication

Module: core/src/biometric/ and core/src/biometric_v2/ Provides OS-level biometric authentication:
Platform implementations:
  • Windows: Windows Hello via Win32 APIs
  • macOS: Touch ID via Security Framework
  • Linux: Polkit for authentication prompts

Password Storage (Keychain)

Module: core/src/password/ Integrates with OS credential storage:
Platform implementations:
  • Windows: Windows Credential Manager (DPAPI)
  • macOS: Keychain Services
  • Linux: Secret Service API (libsecret)

SSH Agent

Module: core/src/ssh_agent/ and ssh_agent/ Provides a native SSH agent implementation:
  • Stores SSH keys securely
  • Handles SSH signing requests
  • Platform-specific socket/pipe communication
  • Peer credential verification
Features:
  • Named pipes on Windows
  • Unix domain sockets on macOS/Linux
  • Request parsing and response handling
  • Secure key storage with encryption

Clipboard

Module: core/src/clipboard.rs Secure clipboard operations with auto-clear functionality.

Autofill

Module: core/src/autofill/ Platform-native autofill integration:
  • macOS: Safari autofill extension provider
  • Windows: Credential provider integration
  • Linux: Desktop environment integration

Process Isolation

Module: core/src/process_isolation/ Sandboxing and process isolation for security-sensitive operations:
  • Windows: Job objects and security attributes
  • macOS: Sandbox profiles
  • Linux: Namespaces and seccomp

Secure Memory

Module: core/src/secure_memory/ Encrypted memory storage for sensitive data:
Features:
  • Memory locking (mlock)
  • Automatic zeroing on drop
  • Platform-specific encryption

Chromium Importer

Module: chromium_importer/ Imports passwords from Chromium-based browsers:
  • Decrypts Chrome/Edge passwords
  • Platform-specific decryption:
    • Windows: DPAPI decryption
    • macOS: Keychain access
    • Linux: Secret Service
  • Isolated helper process for security

N-API Integration

Building Native Modules

Native modules are built using the N-API bindings:
The build process:
  1. Compiles Rust code using cargo build
  2. Uses napi-rs to generate Node.js bindings
  3. Creates platform-specific native modules (.node files)
  4. Copies modules to the appropriate output directory

N-API Module Structure

Importing in TypeScript

Native modules are imported in the main process only:
Never import native modules in the renderer process!Native modules can only be loaded in the main process. Use IPC to expose functionality to the renderer.

Platform-Specific Code

Rust modules use conditional compilation for platform-specific code:
Each platform module implements the same interface:

Workspace Structure

The desktop_native directory is a Cargo workspace:

Key Dependencies

Memory Safety

All native modules use a global allocator that zeros memory on deallocation:
This ensures sensitive data is cleared from memory when freed.

Error Handling

Rust errors are converted to N-API errors:
In TypeScript, these become standard Error objects:

Async Operations

N-API supports async Rust functions:
In TypeScript, these return Promises:

Development Workflow

1. Make Changes to Rust Code

Edit files in desktop_native/core/src/ or desktop_native/napi/src/

2. Build Native Modules

3. Rebuild Electron

4. Test in Main Process

Common Pitfalls

Native Module Loading ErrorsIf you see errors like “Cannot find module ‘@bitwarden/desktop-napi’”:
  1. Ensure you’ve built the native modules: npm run build-native
  2. Run npm run postinstall to rebuild for Electron
  3. Check that you’re importing in the main process, not renderer
  4. Verify the .node file exists in node_modules/@bitwarden/desktop-napi/
Platform-Specific BuildsNative modules must be built for the target platform:
  • Cannot cross-compile Windows modules on macOS
  • macOS modules require Xcode Command Line Tools
  • Linux modules require build-essential packages
Use platform-specific CI runners for production builds.

Testing Native Modules

Rust modules can be tested independently:
For integration testing with Electron:

Debugging Native Modules

Rust Side

Use tracing crate for logging:

TypeScript Side

Log errors from native module calls:

Performance Considerations

  • Native modules run asynchronously to avoid blocking the event loop
  • Heavy computations are offloaded to Rust
  • IPC overhead is minimal for N-API modules (direct function calls)
  • Use native modules for:
    • Cryptographic operations
    • File system operations
    • Network operations
    • OS API interactions

Security Best Practices

  1. Validate inputs in Rust before using them
  2. Zero sensitive memory using zeroize crate
  3. Use secure allocators (already configured globally)
  4. Minimize exposed API surface - only expose necessary functions
  5. Audit dependencies regularly using cargo audit

Future Improvements

Potential areas for enhancement:
  • Migrate more JavaScript crypto operations to Rust
  • Add more comprehensive error types
  • Improve cross-platform consistency
  • Enhanced telemetry and diagnostics
  • Better integration testing framework