disk_cached_image
A Flutter widget and cache service that downloads network images to disk once, serves them from disk on later builds and app launches, and supports TTL, eviction, and clearing.
Features
- Disk persistence — images are stored as files so they survive app restarts and are not downloaded again.
- TTL — pass
maxAgetoDiskCachedImageorDiskImageCache.fetchto re-download a file that is older than the given duration. - Eviction — remove one entry with
DiskImageCache.evict, or the whole cache folder withDiskImageCache.clear. - Atomic writes — a download is first written to a temporary file and then renamed into place, so an interrupted download never leaves a corrupt entry.
- Single-flight downloads — concurrent fetches for the same cache key share one HTTP request and receive the same result.
- Key validation — cache keys are rejected when they could escape the cache folder or clash with Windows reserved device names.
- Cache size —
DiskImageCache.sizereturns the total number of bytes stored on disk. - Gapless refresh — when a stale file is replaced, the new bitmap is shown without a blank frame in between.
Platforms
The package uses dart:io and path_provider to read and write files, so it
supports Android, iOS, macOS, Windows, and Linux. Web is not supported.
Installation
The package is not published on pub.dev yet. Add it to your pubspec.yaml
from this repository with a path dependency:
dependencies:
disk_cached_image:
path: packages/disk_cached_image
You can also depend on the Git repository directly and point at the package folder.
Usage
The DiskCachedImage widget
DiskCachedImage downloads the image once and renders it from disk on every
later build:
import 'package:disk_cached_image/disk_cached_image.dart';
import 'package:flutter/material.dart';
class CoinAvatar extends StatelessWidget {
const CoinAvatar({super.key});
@override
Widget build(BuildContext context) {
return const DiskCachedImage(
url: 'https://picsum.photos/seed/one/200',
cacheKey: 'coin-one',
width: 64,
height: 64,
maxAge: Duration(days: 7),
placeholder: Center(child: CircularProgressIndicator()),
errorBuilder: _buildError,
);
}
static Widget _buildError(
BuildContext context,
Object error,
StackTrace? stackTrace,
) {
return const Icon(Icons.broken_image, size: 64);
}
}
cacheKey is required and identifies the file in the cache. Reuse one
DiskImageCache through the cache parameter to share the underlying HTTP
client between many images:
final cache = DiskImageCache();
DiskCachedImage(
url: 'https://picsum.photos/seed/two/200',
cacheKey: 'coin-two',
cache: cache,
)
The widget shows placeholder while the file is being fetched. errorBuilder
is used for fetch errors; when it is omitted, a broken image icon is shown. It
is also passed to Image.errorBuilder for decode failures; when it is omitted
there, decode failures render nothing in release builds, while in debug builds
Flutter renders its own error placeholder and logs the decode error.
The DiskImageCache API
import 'package:disk_cached_image/disk_cached_image.dart';
final cache = DiskImageCache();
// Fetch a file, downloading it when it is missing or older than maxAge.
final DiskImageCacheResult result = await cache.fetch(
url: Uri.parse('https://picsum.photos/seed/one/200'),
cacheKey: 'coin-one',
maxAge: const Duration(days: 7),
);
print(result.file.path); // path of the cached file
print(result.modified); // modification time used to detect refreshes
// true when this call downloaded the file (or joined an in-flight download)
print(result.downloaded);
// Remove a single entry.
await cache.evict('coin-one');
// Total bytes stored in the cache.
final int bytes = await cache.size();
// Remove every cached file.
await cache.clear();
Notes:
- The cache is keyed by
cacheKeyonly, not by URL. If the URL behind a key changes, callevictor use a new key. - A
nullmaxAgekeeps a file until it is evicted or cleared. fetchthrows anArgumentErrorfor an invalid key, anHttpExceptionfor a non-200 response, and aTimeoutExceptionwhen the request exceeds the cachetimeout(30 seconds by default).DiskImageCachetakes an optionalclientanddirectoryProvider, which is useful for tests.
Example
A runnable app that renders two cached images and clears the cache lives in
example/.
Screenshot
A screenshot for the pub.dev listing is not included yet. Run the example app to see the cached images and the clear-cache action.
License
See LICENSE.
Libraries
- disk_cached_image
- A Flutter widget and cache service that downloads network images to disk once, serves them from disk, and supports TTL, eviction, and clearing.