Skip to main content
Trezor Suite includes a comprehensive collection of utility packages that provide reusable functionality across the monorepo. These packages follow the principle of being small, focused, and free from circular dependencies.

Core Utilities

@trezor/utils

Purpose: General TypeScript utilitiesKey Features:
  • TypedEmitter for type-safe events
  • Deferred promises
  • Throttler for rate limiting
  • Lazy initialization helpers
  • Array and object utilities

@trezor/crypto-utils

Purpose: Cryptographic utilitiesKey Features:
  • Hash functions (SHA256, RIPEMD160)
  • PBKDF2 key derivation
  • Random number generation
  • Base58 encoding/decoding
  • Mnemonic utilities

@trezor/device-utils

Purpose: Device-related utilitiesKey Features:
  • Device detection and identification
  • Firmware version comparison
  • Device capability checks
  • USB descriptor parsing
  • Device model utilities

@trezor/asset-utils

Purpose: Asset and currency utilitiesKey Features:
  • Asset data management
  • Token list handling
  • Currency formatting
  • Icon and metadata access

Environment & Platform

@trezor/env-utils

Purpose: Environment detectionKey Features:
  • Browser detection
  • Node.js environment checks
  • Platform capabilities
  • Feature detection

@trezor/dom-utils

Purpose: DOM manipulation utilitiesKey Features:
  • Safe DOM operations
  • Element queries
  • Event handling
  • Browser compatibility helpers

@trezor/node-utils

Purpose: Node.js-specific utilitiesKey Features:
  • File system helpers
  • Process utilities
  • Path manipulation
  • Environment variable handling

@trezor/react-utils

Purpose: React-specific utilitiesKey Features:
  • Custom hooks
  • Component helpers
  • Context utilities
  • Performance optimization helpers

Data & Validation

@trezor/schema-utils

Purpose: Schema validation utilitiesKey Features:
  • JSON schema validation
  • Type guards
  • Data validation helpers
  • Schema generators

@trezor/type-utils

Purpose: TypeScript type utilitiesKey Features:
  • Advanced type helpers
  • Type guards
  • Conditional types
  • Utility types

@trezor/urls

Purpose: URL managementKey Features:
  • URL constants
  • Backend endpoints
  • Service URLs
  • Link generators

Testing Utilities

@trezor/e2e-utils

Purpose: End-to-end testing utilitiesKey Features:
  • Test helpers
  • Mock data generators
  • Playwright utilities
  • Device emulator integration

Package Deep Dive

@trezor/utils

The main utility package providing core functionality used throughout the codebase.
Type-safe event emitter extending Node.js EventEmitter:
import { TypedEmitter } from '@trezor/utils';

type Events = {
    'data': (value: string) => void;
    'error': (error: Error) => void;
};

class MyClass extends TypedEmitter<Events> {
    sendData(value: string) {
        this.emit('data', value); // Type-safe!
    }
}

const instance = new MyClass();
instance.on('data', (value) => {
    // value is typed as string
    console.log(value);
});
Create promises that can be resolved/rejected externally:
import { createDeferred } from '@trezor/utils';

const deferred = createDeferred<number>();

// Resolve later
setTimeout(() => {
    deferred.resolve(42);
}, 1000);

// Await the promise
const result = await deferred.promise; // 42
Also includes a deferred manager for handling multiple promises:
import { createDeferredManager } from '@trezor/utils';

const manager = createDeferredManager();

const { promiseId, promise } = manager.create<string>();
// Later...
manager.resolve(promiseId, 'done');
Rate-limit function execution:
import { Throttler } from '@trezor/utils';

const throttler = new Throttler(1000); // Max once per second

throttler.throttle(() => {
    console.log('This runs max once per second');
});
Defer resource initialization until first use:
import { createLazy } from '@trezor/utils';

const lazyResource = createLazy(
    () => expensiveInit(),    // Init function
    (resource) => cleanup()    // Cleanup function
);

const resource = await lazyResource.getOrInit();
// Later...
lazyResource.dispose();
Common data manipulation helpers:
import { arrayDistinct, objectPartition } from '@trezor/utils';

// Remove duplicates
const unique = arrayDistinct([1, 2, 2, 3]); // [1, 2, 3]

// Partition object by predicate
const [matched, rest] = objectPartition(
    { a: 1, b: 2, c: 3 },
    (key, value) => value > 1
);
// matched: { b: 2, c: 3 }
// rest: { a: 1 }

@trezor/crypto-utils

Cryptographic operations needed across Suite.
import { sha256, ripemd160 } from '@trezor/crypto-utils';

const hash = sha256(Buffer.from('hello'));
const hash160 = ripemd160(Buffer.from('world'));
import { pbkdf2 } from '@trezor/crypto-utils';

const key = await pbkdf2(
    'password',
    'salt',
    100000,  // iterations
    32       // key length
);
import { base58 } from '@trezor/crypto-utils';

const encoded = base58.encode(Buffer.from('data'));
const decoded = base58.decode(encoded);
import { randomBytes } from '@trezor/crypto-utils';

const random = randomBytes(32); // 32 random bytes

@trezor/device-utils

Device detection and capability checking.
import { getDeviceModel, getDeviceFeatures } from '@trezor/device-utils';

const model = getDeviceModel(device);
// 'T' for Trezor Model T
// '1' for Trezor One

const features = getDeviceFeatures(device);
import { versionCompare, isNewerOrEqual } from '@trezor/device-utils';

const comparison = versionCompare('2.5.3', '2.5.1');
// Returns: 1 (first is newer)

const isNewer = isNewerOrEqual('2.5.3', '2.5.1'); // true
import { hasCapability } from '@trezor/device-utils';

const canDoTaproot = hasCapability(device, 'Capability_Taproot');

@trezor/env-utils

Environment and platform detection.
import { 
    isWeb, 
    isDesktop, 
    isAndroid, 
    isIOS,
    getBrowserName,
    getBrowserVersion
} from '@trezor/env-utils';

if (isWeb()) {
    console.log('Running in browser:', getBrowserName());
}

if (isDesktop()) {
    console.log('Running in Electron');
}

if (isAndroid() || isIOS()) {
    console.log('Running on mobile');
}

@trezor/schema-utils

Data validation and schema management.
import { validateData, isValidAddress } from '@trezor/schema-utils';

// Validate against JSON schema
const result = validateData(data, schema);
if (!result.valid) {
    console.error('Validation errors:', result.errors);
}

// Type guard example
function isTransaction(obj: unknown): obj is Transaction {
    return validateData(obj, transactionSchema).valid;
}

@trezor/type-utils

Advanced TypeScript type utilities.
import type { 
    DeepPartial,
    Require,
    Without,
    XOR
} from '@trezor/type-utils';

// Make all properties optional recursively
type PartialConfig = DeepPartial<Config>;

// Require specific properties
type RequiredName = Require<User, 'name'>;

// Exclude specific properties
type WithoutPassword = Without<User, 'password'>;

// Exclusive OR - only one of the types
type Payment = XOR<CreditCard, BankAccount>;

Common Patterns

Using Multiple Utilities Together

import { TypedEmitter, createDeferred, Throttler } from '@trezor/utils';
import { sha256 } from '@trezor/crypto-utils';
import { isWeb } from '@trezor/env-utils';

type Events = {
    'hashComputed': (hash: Buffer) => void;
};

class HashService extends TypedEmitter<Events> {
    private throttler = new Throttler(100);
    
    async computeHash(data: string): Promise<Buffer> {
        const deferred = createDeferred<Buffer>();
        
        this.throttler.throttle(async () => {
            const hash = sha256(Buffer.from(data));
            this.emit('hashComputed', hash);
            deferred.resolve(hash);
        });
        
        return deferred.promise;
    }
}

if (isWeb()) {
    const service = new HashService();
    service.on('hashComputed', (hash) => {
        console.log('Hash:', hash.toString('hex'));
    });
}

Best Practices

Use named imports to enable tree-shaking:
// Good
import { sha256, base58 } from '@trezor/crypto-utils';

// Avoid
import * as crypto from '@trezor/crypto-utils';
Check utility packages before implementing common functionality:
// Instead of implementing your own
function myArrayUnique(arr: number[]) { /* ... */ }

// Use the existing utility
import { arrayDistinct } from '@trezor/utils';
const unique = arrayDistinct(arr);
When creating new utility functions:
  • Keep them small and focused
  • Make them pure functions when possible
  • Add comprehensive tests
  • Document with JSDoc comments
Leverage TypeScript features in utils:
// Instead of plain EventEmitter
import { EventEmitter } from 'events';

// Use TypedEmitter for type safety
import { TypedEmitter } from '@trezor/utils';

Adding New Utilities

When adding utilities to an existing package:
1

Choose the Right Package

Place utilities in the most specific appropriate package:
  • General utils → @trezor/utils
  • Crypto-specific → @trezor/crypto-utils
  • React-specific → @trezor/react-utils
2

Write Tests

Add comprehensive unit tests:
// arrayDistinct.test.ts
import { arrayDistinct } from './arrayDistinct';

describe('arrayDistinct', () => {
    it('removes duplicates', () => {
        expect(arrayDistinct([1, 2, 2, 3])).toEqual([1, 2, 3]);
    });
    
    it('handles empty array', () => {
        expect(arrayDistinct([])).toEqual([]);
    });
});
3

Document the Function

Add JSDoc comments:
/**
 * Removes duplicate values from an array.
 * 
 * @param arr - The input array
 * @returns A new array with duplicates removed
 * 
 * @example
 * arrayDistinct([1, 2, 2, 3]) // [1, 2, 3]
 */
export const arrayDistinct = <T>(arr: T[]): T[] => {
    return Array.from(new Set(arr));
};
4

Export from Index

Add to the package’s main export:
// index.ts
export { arrayDistinct } from './arrayDistinct';

Package Overview

Browse all packages in the monorepo

Creating Packages

Learn how to create new utility packages

TypeScript Guide

TypeScript conventions and patterns

Testing

How to test your utilities

Build docs developers (and LLMs) love