Super fast and secure cached image component for React Native applications built with Expo.
- π Fast image loading with local caching
- π Secure file handling and sanitized cache keys
- β±οΈ Configurable cache expiration
- π Automatic cache cleanup
- π± Full TypeScript support
- π¨ Customizable placeholder content
# Using npm
npm install expo-cached-image
# Using yarn
yarn add expo-cached-image
# Using expo
npx expo install expo-cached-imageimport CachedImage from 'expo-cached-image'
import { ActivityIndicator } from 'react-native'
const MyComponent = () => {
  return (
    <CachedImage
      source={{ 
        uri: 'https://example.com/image.jpg',
        headers: { 'Authorization': 'Bearer your-token' }, // Optional
        expiresIn: 86400, // Optional: Cache expiration in seconds (24 hours)
      }}
      cacheKey="unique-image-key" // Required: Unique identifier for the image
      placeholderContent={( // Optional: Component to show while loading
        <ActivityIndicator 
          color="#999999"
          size="small"
          style={{ flex: 1, justifyContent: "center" }}
        />
      )}
      style={{ width: 200, height: 200 }}
      resizeMode="contain"
    />
  )
}| Prop | Type | Required | Description | 
|---|---|---|---|
| source | ImageSource | Yes | Image source object containing uri, optional headers and expiration | 
| cacheKey | string | Yes | Unique identifier for caching the image | 
| placeholderContent | ReactNode | No | Component to display while image is loading | 
| ...ImageProps | ImageProps | No | All props from React Native's Image component | 
| Property | Type | Required | Description | 
|---|---|---|---|
| uri | string | Yes | URL of the image to load and cache | 
| headers | object | No | Request headers for image download | 
| expiresIn | number | No | Cache expiration time in seconds | 
import { CacheManager } from 'expo-cached-image'const uri = await CacheManager.addToCache({
  file: '/path/to/local/file',
  key: 'unique-key'
})const uri = await CacheManager.getCachedUri({
  key: 'unique-key'
})const result = await CacheManager.downloadAsync({
  uri: 'https://example.com/image.jpg',
  key: 'unique-key',
  options: {
    headers: {
      'Authorization': 'Bearer token'
    }
  }
})const metadata = await CacheManager.getMetadata({
  key: 'unique-key'
})
if (metadata) {
  console.log('File exists:', metadata.exists)
  console.log('File size:', metadata.size, 'bytes')
  console.log('Last modified:', metadata.modificationTime)
  console.log('File path:', metadata.uri)
} else {
  console.log('File not found or error occurred')
}Returns metadata for a cached item, including file existence, size, modification time, and file path. Returns null if the file doesn't exist or an error occurs.
- Always use HTTPS URLs for image sources
- Cache keys are automatically sanitized to prevent path traversal and other filesystem-related vulnerabilities
- Only alphanumeric characters, dashes, and underscores are allowed
- Keys are limited to 100 characters
- Leading dashes and periods are replaced with underscores
 
- Implement proper token/credentials management for authenticated requests
- Be mindful of storage space when caching large images
- Consider implementing cache size limits in your application
- Use meaningful and unique cache keys
- Keys will be automatically sanitized, but it's best to use simple alphanumeric identifiers
- Example: "user-123-profile-image" or "product_456_thumbnail"
 
- Implement placeholder content for better UX
- Set appropriate cache expiration times
- Handle errors gracefully
- Clean up unused cached images periodically
const SecureImageComponent = () => {
  const [error, setError] = useState(false);
  const handleError = () => {
    setError(true);
    // Implement your error handling logic
  };
  return (
    <CachedImage
      source={{
        uri: 'https://secure-site.com/image.jpg',
        headers: {
          'Authorization': 'Bearer token',
          'Accept': 'image/*'
        },
        expiresIn: 3600 // 1 hour
      }}
      cacheKey="secure-image-1"
      onError={handleError}
      placeholderContent={
        error ? (
          <ErrorPlaceholder />
        ) : (
          <LoadingPlaceholder />
        )
      }
    />
  );
};Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
- github - Photo sharing react-native source code.
- WiSaw on the web - here is how it looks on the web.
- install iOS app
- install Android app
If you're having any problem, please raise an issue on GitHub.