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
maxDiskCacheBytes: 5242880, // Ceiling on disk; oldest dropped first
},
});

Configuration Optionsโ€‹

OptionTypeDefaultDescription
maxMemoryItemsnumber500Maximum icons in memory cache (LRU)
enableDiskCachebooleantrueEnable persistent disk cache (MMKV)
diskCachePrefixstring'rn-iconify:'Key prefix for disk cache entries
maxDiskCacheBytesnumber5242880Largest the disk cache may grow. Oldest icons are dropped first. 0 keeps everything
note

The disk cache is MMKV โ€” ordinary persistent storage, not the directory the operating system empties under pressure. The ceiling is what stops every icon an app has ever rendered from staying on the device for as long as the app is installed.

It is enforced every twenty-five writes rather than on each one, because measuring means walking every key. The cache can therefore sit a little above the ceiling between checks โ€” around twenty-five kilobytes at the default.

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/dev';

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โ€‹