Skip to main content

Cache Management

rn-iconify includes a multi-tier caching system for optimal performance. This guide covers configuration and management of the cache.

Cache Overviewโ€‹

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Cache Hierarchy โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ โ”‚
โ”‚ Request: getIcon('mdi:home') โ”‚
โ”‚ โ”‚ โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Memory Cache โ”‚ โ† ~0.01ms (instant) โ”‚
โ”‚ โ”‚ (LRU, in-memory) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ miss โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Bundled Icons โ”‚ โ† ~0ms (compiled in) โ”‚
โ”‚ โ”‚ (Babel plugin) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ miss โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Disk Cache โ”‚ โ† ~0.1ms (MMKV/JSI) โ”‚
โ”‚ โ”‚ (Native storage) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚ miss โ”‚
โ”‚ โ–ผ โ”‚
โ”‚ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”‚
โ”‚ โ”‚ Network โ”‚ โ† 100-500ms โ”‚
โ”‚ โ”‚ (Iconify API) โ”‚ โ”‚
โ”‚ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ”‚
โ”‚ โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

CacheManagerโ€‹

The CacheManager singleton provides full control over caching:

import { CacheManager } from 'rn-iconify';

// Get icon from cache (any layer)
const icon = CacheManager.get('mdi:home');

// Check if icon is cached
const isCached = CacheManager.has('mdi:home');

// Store icon in cache
CacheManager.set('mdi:home', iconData);

// Get cache statistics
const stats = CacheManager.getStats();
console.log({
memoryCount: stats.memoryCount, // Icons in memory
bundledCount: stats.bundledCount, // Bundled icons
diskCount: stats.diskCount, // Icons on disk
diskSizeBytes: stats.diskSizeBytes, // Disk usage
});

Configurationโ€‹

Basic Configurationโ€‹

import { configure } from 'rn-iconify';

configure({
cache: {
maxMemoryItems: 500, // Max icons in memory
enableDiskCache: true, // Enable disk caching (MMKV)
diskCachePrefix: 'rn-iconify:', // Cache key prefix
},
});

Configuration Optionsโ€‹

OptionTypeDefaultDescription
maxMemoryItemsnumber500Maximum icons in memory cache (LRU)
enableDiskCachebooleantrueEnable persistent disk cache (MMKV)
diskCachePrefixstring'rn-iconify:'Key prefix for disk cache entries

Clearing Cacheโ€‹

Clear All Cachesโ€‹

import { CacheManager } from 'rn-iconify';

// Clear everything (memory + disk)
CacheManager.clear();

Clear Memory Onlyโ€‹

import { CacheManager } from 'rn-iconify';

// Clear only memory cache (disk remains)
CacheManager.clearMemory();

Clear Specific Iconโ€‹

import { CacheManager } from 'rn-iconify';

// Delete specific icon from cache
CacheManager.delete('mdi:home');

Prefetchingโ€‹

Basic Prefetchingโ€‹

import { prefetchIcons } from 'rn-iconify';

// Prefetch icons at app startup
async function initApp() {
await prefetchIcons([
'mdi:home',
'mdi:settings',
'mdi:account',
'heroicons:user',
'heroicons:cog',
]);
}

Prefetch Resultโ€‹

import { prefetchIcons } from 'rn-iconify';

const result = await prefetchIcons([
'mdi:home',
'mdi:settings',
'unknown:icon',
]);

console.log({
success: result.success, // ['mdi:home', 'mdi:settings']
failed: result.failed, // ['unknown:icon']
});

Prefetch by Icon Setโ€‹

import { prefetchIcons, fetchCollection } from 'rn-iconify';

// Get icon names from a collection, then prefetch
async function prefetchIconSet(prefix: string, limit = 100) {
const collection = await fetchCollection(prefix);
const iconsToFetch = collection.icons.slice(0, limit).map(name => `${prefix}:${name}`);
return prefetchIcons(iconsToFetch);
}

// Usage
await prefetchIconSet('heroicons', 50); // First 50 icons

Cache Warmingโ€‹

Warm the cache on app start by prefetching common icons:

import { prefetchIcons, CacheManager } from 'rn-iconify';

// Warm cache from disk to memory
async function onAppStart() {
// Prefetch priority icons first
await prefetchIcons([
'mdi:home',
'mdi:settings',
'mdi:account',
'mdi:menu',
// Add your commonly used icons
]);

console.log('Cache warmed:', CacheManager.getStats().memoryCount);
}

Offline Bundlesโ€‹

Load pre-bundled icons for offline support:

import { loadOfflineBundle, CacheManager } from 'rn-iconify';
import iconBundle from './assets/icons.bundle.json';

// Load bundle into cache
const result = loadOfflineBundle(iconBundle);

console.log({
loaded: result.loaded, // Number of icons loaded
skipped: result.skipped, // Already cached (skipped)
total: result.total, // Total icons in bundle
version: result.version, // Bundle version
loadTimeMs: result.loadTimeMs, // Load time in milliseconds
});

// Verify
console.log('Bundle loaded:', CacheManager.has('mdi:home'));

Cache Statisticsโ€‹

Get Current Statsโ€‹

import { CacheManager } from 'rn-iconify';

const stats = CacheManager.getStats();

console.log({
// Counts
memoryCount: stats.memoryCount, // Icons in memory cache
bundledCount: stats.bundledCount, // Icons from offline bundles
diskCount: stats.diskCount, // Icons in disk cache
diskSizeBytes: stats.diskSizeBytes, // Disk cache size in bytes
});

Stats Return Typeโ€‹

interface CacheStats {
memoryCount: number; // Icons in memory (LRU cache)
bundledCount: number; // Icons from loadOfflineBundle()
diskCount: number; // Icons persisted to MMKV
diskSizeBytes: number; // Total disk cache size
}

Cache Persistenceโ€‹

Default Behaviorโ€‹

By default, rn-iconify persists the disk cache across app restarts:

// First app launch
<Mdi name="home" /> // Fetches from network, caches to disk

// Second app launch
<Mdi name="home" /> // Loads from disk cache instantly

Disable Persistenceโ€‹

import { configure } from 'rn-iconify';

configure({
cache: {
enableDiskCache: false, // Memory-only caching
},
});

Custom Cache Prefixโ€‹

import { configure } from 'rn-iconify';

configure({
cache: {
diskCachePrefix: 'my-app-icons:', // Custom cache key prefix
},
});

Memory Managementโ€‹

LRU Evictionโ€‹

Memory cache uses LRU (Least Recently Used) eviction:

import { configure } from 'rn-iconify';

configure({
cache: {
maxMemoryItems: 100, // Keep max 100 icons in memory
},
});

// When cache is full, oldest unused icons are evicted automatically

Native Cache Integrationโ€‹

When the native module is available, CacheManager provides additional methods:

Check Native Availabilityโ€‹

import { CacheManager } from 'rn-iconify';

if (CacheManager.isNativeAvailable()) {
console.log('Native cache enabled');
}

Get Native Statsโ€‹

import { CacheManager } from 'rn-iconify';

async function logNativeStats() {
const nativeStats = await CacheManager.getNativeStats();

if (nativeStats) {
console.log({
diskCount: nativeStats.diskCount,
diskSizeBytes: nativeStats.diskSizeBytes,
hitRate: nativeStats.hitRate,
});
}
}

Clear Native Cacheโ€‹

import { CacheManager } from 'rn-iconify';

async function clearAllCaches() {
// Clear JS caches (memory + disk)
CacheManager.clear();

// Clear native module cache separately
await CacheManager.clearNative();

console.log('All caches cleared');
}

Prefetch with Native Moduleโ€‹

import { CacheManager, fetchIcon } from 'rn-iconify';

async function prefetchIcons(iconNames: string[]) {
// Uses native module if available, JS fallback otherwise
const result = await CacheManager.prefetch(
iconNames,
fetchIcon // Fallback fetch function
);

console.log({
success: result.success.length,
failed: result.failed.length,
});
}

Best Practicesโ€‹

1. Prefetch Critical Iconsโ€‹

// App.tsx
useEffect(() => {
prefetchIcons([
'mdi:home',
'mdi:menu',
'mdi:close',
'mdi:arrow-left',
// Navigation and common UI icons
]);
}, []);

2. Use Bundles for Offline Supportโ€‹

// For critical icons that must work offline
import criticalBundle from './bundles/critical.json';

loadOfflineBundle(criticalBundle);

3. Configure Appropriate Cache Sizeโ€‹

// Small app with few icons
configure({ cache: { maxMemoryItems: 50 } });

// Large app with many icons
configure({ cache: { maxMemoryItems: 500 } });

4. Clear Cache on User Logoutโ€‹

function handleLogout() {
// Clear user data...

// Optionally clear icon cache
CacheManager.clear();
}

5. Monitor Cache in Developmentโ€‹

if (__DEV__) {
setInterval(() => {
const stats = CacheManager.getStats();
console.log('Cache stats:', stats);
}, 10000);
}

Troubleshootingโ€‹

Cache Not Persistingโ€‹

import { CacheManager, getConfiguration } from 'rn-iconify';

// Check if disk cache is enabled
const stats = CacheManager.getStats();
if (stats.diskCount === 0) {
console.warn('Disk cache may be disabled or failed to initialize');

// Check configuration
const config = getConfiguration();
console.log('enableDiskCache:', config.cache.enableDiskCache);
}

High Memory Usageโ€‹

import { CacheManager, configure } from 'rn-iconify';

// Check memory cache count
const stats = CacheManager.getStats();
if (stats.memoryCount > 500) {
console.warn('High memory icon count, consider reducing maxMemoryItems');

// Clear memory cache (disk cache persists)
CacheManager.clearMemory();

// Reduce future cache size
configure({ cache: { maxMemoryItems: 200 } });
}

Cache Missesโ€‹

import { enablePerformanceMonitoring, getPerformanceReport } from 'rn-iconify';

enablePerformanceMonitoring();

// After some time...
const report = getPerformanceReport();
if (report.cacheStats.hitRate < 0.8) {
console.warn('Low cache hit rate, consider prefetching icons');
}

Cache Migrationโ€‹

When upgrading rn-iconify versions, you may want to clear the cache:

import { CacheManager } from 'rn-iconify';
import AsyncStorage from '@react-native-async-storage/async-storage';

const LIBRARY_VERSION = '2.0.0'; // Update when you upgrade rn-iconify

async function checkCacheMigration() {
const storedVersion = await AsyncStorage.getItem('rn-iconify-version');

if (storedVersion !== LIBRARY_VERSION) {
// Clear cache on version change
CacheManager.clear();
await AsyncStorage.setItem('rn-iconify-version', LIBRARY_VERSION);
console.log('Cache cleared for version upgrade');
}
}

Next Stepsโ€‹