Skip to main content
Credo is platform-agnostic and can run in Node.js, React Native, and browser environments. Each platform requires specific dependencies and configuration.

Platform Dependencies

Credo requires platform-specific implementations for:
  • File System - Storage operations
  • Fetch API - HTTP requests
  • WebSocket - Real-time communication
  • Event Emitter - Event handling

Node.js Setup

Installation

npm install @credo-ts/core @credo-ts/node @credo-ts/askar @openwallet-foundation/askar-nodejs

Basic Configuration

import { Agent } from '@credo-ts/core'
import { agentDependencies } from '@credo-ts/node'
import { AskarModule } from '@credo-ts/askar'
import { askar } from '@openwallet-foundation/askar-nodejs'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    askar: new AskarModule({
      askar,
      store: {
        id: 'my-agent',
        key: 'my-secure-key',
      },
    }),
  },
})

await agent.initialize()

Node.js Dependencies Breakdown

The agentDependencies from @credo-ts/node provides:
import { EventEmitter } from 'events'
import { WebSocket } from 'ws'
import { NodeFileSystem } from '@credo-ts/node'

const agentDependencies = {
  FileSystem: NodeFileSystem,
  fetch: global.fetch,
  EventEmitterClass: EventEmitter,
  WebSocketClass: WebSocket,
}

Node.js Transports

Node.js supports HTTP and WebSocket transports:
import { DidCommModule } from '@credo-ts/didcomm'
import {
  DidCommHttpInboundTransport,
  DidCommWsInboundTransport,
} from '@credo-ts/node'
import {
  DidCommHttpOutboundTransport,
  DidCommWsOutboundTransport,
} from '@credo-ts/didcomm'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      transports: {
        inbound: [
          new DidCommHttpInboundTransport({ port: 3000 }),
          new DidCommWsInboundTransport({ port: 3001 }),
        ],
        outbound: [
          new DidCommHttpOutboundTransport(),
          new DidCommWsOutboundTransport(),
        ],
      },
    }),
  },
})

Node.js Key Management

Optional hardware-backed key storage:
import {
  NodeKeyManagementService,
  NodeInMemoryKeyManagementStorage,
} from '@credo-ts/node'
import { Kms } from '@credo-ts/core'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    kms: new Kms.KeyManagementModule({
      backends: [
        new NodeKeyManagementService(
          new NodeInMemoryKeyManagementStorage()
        ),
      ],
    }),
  },
})

React Native Setup

Installation

npm install @credo-ts/core @credo-ts/react-native @credo-ts/askar @openwallet-foundation/askar-react-native
npm install react-native-get-random-values

Additional Dependencies

React Native requires polyfills:
npm install react-native-fs react-native-get-random-values

Basic Configuration

import 'react-native-get-random-values' // Must be first import
import { Agent } from '@credo-ts/core'
import { agentDependencies } from '@credo-ts/react-native'
import { AskarModule } from '@credo-ts/askar'
import { askar } from '@openwallet-foundation/askar-react-native'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    askar: new AskarModule({
      askar,
      store: {
        id: 'my-mobile-agent',
        key: 'secure-mobile-key',
      },
    }),
  },
})

await agent.initialize()

React Native Dependencies Breakdown

import { EventEmitter } from 'events'
import { ReactNativeFileSystem } from '@credo-ts/react-native'

const agentDependencies = {
  FileSystem: ReactNativeFileSystem,
  fetch: global.fetch,
  EventEmitterClass: EventEmitter,
  WebSocketClass: global.WebSocket,
}

React Native Transports

Mobile agents typically act as clients (no inbound transports):
import { DidCommModule, DidCommHttpOutboundTransport } from '@credo-ts/didcomm'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      transports: {
        outbound: [new DidCommHttpOutboundTransport()],
      },
    }),
  },
})

Secure Key Management (React Native)

Use the device’s secure enclave:
import { SecureEnvironmentKeyManagementService } from '@credo-ts/react-native'
import { Kms } from '@credo-ts/core'

const agent = new Agent({
  config: {},
  dependencies: agentDependencies,
  modules: {
    kms: new Kms.KeyManagementModule({
      backends: [
        new SecureEnvironmentKeyManagementService(),
      ],
    }),
  },
})
This uses iOS Keychain and Android Keystore for secure key storage.

Important React Native Notes

Import Order Matters: Always import react-native-get-random-values first:
import 'react-native-get-random-values' // MUST be first
import { Agent } from '@credo-ts/core'
// ... other imports
Metro Configuration: You may need to configure Metro bundler for certain polyfills. Check the React Native documentation for details.

Platform Comparison

Best for:
  • Server-side agents
  • Mediators and cloud agents
  • Enterprise backends
  • Issuer/verifier services
Features:
  • Full DIDComm support (inbound + outbound)
  • HTTP and WebSocket transports
  • File system storage
  • Hardware key storage support
  • Production-ready performance
Storage:
askar: new AskarModule({
  askar,
  store: {
    id: 'agent-storage',
    key: 'secure-key',
    path: '/var/lib/agent/storage', // Optional path
  },
})

File System Differences

Node.js File System

import { NodeFileSystem } from '@credo-ts/node'

const fileSystem = new NodeFileSystem()

// Full file system access
await fileSystem.write('/path/to/file.txt', 'content')
const content = await fileSystem.read('/path/to/file.txt')

React Native File System

import { ReactNativeFileSystem } from '@credo-ts/react-native'

const fileSystem = new ReactNativeFileSystem()

// Scoped to app's private directory
await fileSystem.write('file.txt', 'content')
const content = await fileSystem.read('file.txt')

Storage Paths

// Specify custom storage path
new AskarModule({
  askar,
  store: {
    id: 'production-agent',
    key: process.env.STORAGE_KEY,
    path: '/var/lib/credo/storage',
  },
})

// Default: current directory

Network Configuration

Node.js (Server)

const agent = new Agent({
  config: {
    allowInsecureHttpUrls: false, // Production: use HTTPS
  },
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      endpoints: [
        'https://agent.example.com',
        'wss://agent.example.com/ws',
      ],
    }),
  },
})

React Native (Client)

const agent = new Agent({
  config: {
    allowInsecureHttpUrls: __DEV__, // Only in development
  },
  dependencies: agentDependencies,
  modules: {
    didcomm: new DidCommModule({
      // No endpoints - client only
      transports: {
        outbound: [new DidCommHttpOutboundTransport()],
      },
    }),
  },
})

Complete Examples

import { Agent, ConsoleLogger, LogLevel } from '@credo-ts/core'
import { agentDependencies, DidCommHttpInboundTransport } from '@credo-ts/node'
import { AskarModule } from '@credo-ts/askar'
import { DidCommModule, DidCommHttpOutboundTransport } from '@credo-ts/didcomm'
import { askar } from '@openwallet-foundation/askar-nodejs'

const agent = new Agent({
  config: {
    logger: new ConsoleLogger(LogLevel.info),
    allowInsecureHttpUrls: false,
  },
  dependencies: agentDependencies,
  modules: {
    askar: new AskarModule({
      askar,
      store: {
        id: 'server-agent',
        key: process.env.STORAGE_KEY!,
        path: '/var/lib/agent/storage',
      },
    }),
    didcomm: new DidCommModule({
      endpoints: ['https://agent.example.com'],
      transports: {
        inbound: [new DidCommHttpInboundTransport({ port: 3000 })],
        outbound: [new DidCommHttpOutboundTransport()],
      },
    }),
  },
})

await agent.initialize()
console.log('Server agent ready')

Platform-Specific Features

Node.js Only

  • Inbound transports - Accept incoming connections
  • File system paths - Full control over storage location
  • Process signals - Handle SIGTERM/SIGINT for graceful shutdown
  • Environment variables - Easy configuration management

React Native Only

  • Secure enclave - Hardware-backed key storage
  • Biometric auth - Integrate with device biometrics
  • App lifecycle - Handle background/foreground transitions
  • Deep linking - Handle credential offers via URLs

Performance Considerations

  • Use connection pooling for databases
  • Enable clustering for multiple CPU cores
  • Configure appropriate timeout values
  • Monitor memory usage for long-running processes
  • Minimize bundle size (use Hermes engine)
  • Offload crypto operations to native modules
  • Cache frequently accessed data
  • Handle app suspension gracefully

Troubleshooting

Node.js Issues

Port already in use:
new DidCommHttpInboundTransport({ port: 3000 })
// Error: EADDRINUSE

// Solution: Use a different port or kill the process
File permissions:
store: { path: '/var/lib/agent' }
// Error: EACCES

// Solution: Ensure write permissions or use different path

React Native Issues

Random number generation:
// Error: crypto.getRandomValues not found

// Solution: Import polyfill first
import 'react-native-get-random-values'
Metro bundler:
// Error: Unable to resolve module

// Solution: Clear cache
npx react-native start --reset-cache

Next Steps

Agent Configuration

Configure your agent for your platform

DIDComm Setup

Set up messaging for your platform

Multi-Tenancy

Server-side multi-tenant setup

OpenID4VC

Mobile wallet credential flows

Build docs developers (and LLMs) love