GhostCache is a lightweight, auto-caching wrapper for HTTP requests made with fetch()
and Axios
. It improves performance and reduces redundant network requests by automatically caching API responses. GhostCache supports multiple storage backends including:
- In-Memory Storage (default)
- localStorage
- sessionStorage
- IndexedDB
- Redis (via a provided adapter)
GhostCache is ideal for web applications, React apps, Node.js projects, and any environment that makes HTTP requests.
Currently available as a Node.js package on NPM. NPM Page: https://www.npmjs.com/package/ghost-cache
- Features
- Installation
- Configuration Options
- Usage Examples
- Storage Adapters
- Advanced Examples
- API Reference
- Testing
- Demo Script
- Contributing
- License
- Automatic Caching: Intercepts requests via
fetch()
and Axios. - Multiple Storage Options: Choose your preferred storage backend.
- Configurable TTL: Set cache expiry time in milliseconds.
- Cache Size Limiting: Limit the number of in-memory entries.
- Manual Cache API: Set and retrieve cache entries manually.
- Pluggable: Easily integrate with any HTTP client.
Install GhostCache via npm or Yarn:
npm install ghost-cache
# or
yarn add ghost-cache
(Optional, but encouraged): Install cross-fetch
for better compatibility across environments:
npm install --save-dev cross-fetch
When enabling GhostCache, you can pass an options object to customize its behavior:
- ttl: Time-to-live for cache entries in milliseconds (default: 60000).
- persistent: Boolean to enable persistent storage (default: false).
- maxEntries: Maximum number of in-memory cache entries (default: 100).
- storage: Choose storage adapter. Options:
'localStorage'
'sessionStorage'
'indexedDB'
'redis'
(requires a valid RedisAdapter instance)- Or provide a custom storage adapter object that implements the IStorageAdapter interface (for your flexibility and convenience).
Example:
import { enableGhostCache } from "ghost-cache";
enableGhostCache({
ttl: 120000, // Cache entries expire in 2 minutes
persistent: true, // Enable persistent caching
maxEntries: 200, // Allow up to 200 in-memory entries
storage: "localStorage", // Use localStorage for persistence
});
Enable caching and make HTTP requests using the native fetch API. GhostCache will intercept and cache the responses.
import { enableGhostCache, disableGhostCache } from "ghost-cache";
// Enable GhostCache with default options (TTL: 60 sec, in-memory caching)
enableGhostCache();
// Regular fetch calls remain unchanged
fetch("https://pokeapi.co/api/v2/pokemon/ditto")
.then((res) => res.json())
.then((data) => console.log("Fetched data:", data));
// Disable GhostCache to restore original fetch behavior
// disableGhostCache();
You can also integrate GhostCache with Axios by registering your Axios instance.
import axios from "axios";
import { enableGhostCache, registerAxios } from "ghost-cache";
// Enable caching with 30 seconds TTL and persistent localStorage
enableGhostCache({ ttl: 30000, persistent: true, storage: "localStorage" });
// Create an Axios instance and register it with GhostCache
const api = axios.create({ baseURL: "https://pokeapi.co/api/v2" });
registerAxios(api);
// Make requests using Axios. Subsequent calls will be served from the cache.
api
.get("/pokemon/ditto")
.then((response) => console.log("Axios fetched:", response.data));
GhostCache provides methods to manually set and retrieve cache entries.
import { setCache, getCache } from "ghost-cache";
// Manually store a cache entry
await setCache("user-profile", { name: "Alice", age: 30 });
// Retrieve the manually stored cache entry
const profile = await getCache("user-profile");
console.log("Manual cache:", profile);
Enable persistent caching using the browser's localStorage:
enableGhostCache({
persistent: true,
storage: "localStorage",
});
Use sessionStorage for caching that lasts only for the browser session:
enableGhostCache({
persistent: true,
storage: "sessionStorage",
});
Use IndexedDB for structured, persistent storage:
enableGhostCache({
persistent: true,
storage: "indexedDB",
});
For server-side caching, you can use Redis by providing a RedisAdapter instance. Ensure you have a valid Redis client (for example, using the redis
package):
import { createClient } from "redis";
import { RedisAdapter } from "ghost-cache/dist/storage/RedisAdapter";
const redisClient = createClient();
await redisClient.connect();
enableGhostCache({
persistent: true,
storage: new RedisAdapter(redisClient),
});
Integrate GhostCache in a React app to cache API responses automatically.
// App.tsx
import React, { useEffect, useState } from "react";
import { enableGhostCache } from "ghost-cache";
enableGhostCache({ ttl: 60000, persistent: true, storage: "localStorage" });
const App: React.FC = () => {
const [pokemon, setPokemon] = useState<any>(null);
useEffect(() => {
fetch("https://pokeapi.co/api/v2/pokemon/ditto")
.then((res) => res.json())
.then(setPokemon);
}, []);
return (
<div>
<h1>GhostCache Example in React</h1>
{pokemon ? (
<pre>{JSON.stringify(pokemon, null, 2)}</pre>
) : (
<p>Loading...</p>
)}
</div>
);
};
export default App;
If you use GhostCache in a Node.js environment (using Axios), you can enable caching similarly. Note that persistent caching may require a server-side storage adapter like Redis.
// node-example.ts
import axios from "axios";
import { enableGhostCache, registerAxios } from "ghost-cache";
// Enable caching (TTL: 60 sec, in-memory caching)
enableGhostCache({ ttl: 60000 });
// Create and register an Axios instance
const api = axios.create({ baseURL: "https://pokeapi.co/api/v2" });
registerAxios(api);
// Use Axios to make requests
api
.get("/pokemon/ditto")
.then((response) => {
console.log("Node.js Axios fetched:", response.data);
})
.catch((error) => {
console.error("Error:", error);
});
-
enableGhostCache(options?: GhostCacheOptions): void
Enables GhostCache. Automatically intercepts HTTP requests made withfetch()
and Axios. -
clearGhostCache(): void
Clears all cache entries from memory (and persistent storage if enabled). -
disableGhostCache(): void
Disables GhostCache and restores the original HTTP request methods. -
setCache(key: string, value: any): Promise
Manually sets a cache entry. -
getCache<T = any>(key: string): Promise<T | null>
Retrieves a manually set cache entry. -
registerAxios(instance: AxiosInstance): void
Registers an Axios instance so that its requests are intercepted and cached.
GhostCache comes with a comprehensive Jest test suite. To run tests:
-
Ensure you have installed dependencies:
npm install
-
Run tests with:
npm test
Tests use the Pokémon API (https://pokeapi.co/api/v2/pokemon/ditto
) to verify that caching works for both fetch()
and Axios requests.
Note: There may be path/import issues. If you encounter any, please check the test files and adjust the import paths accordingly.
To run a demo script that showcases GhostCache in action, use the following command:
npm run demo
This will execute a script that demonstrates caching with both fetch()
and Axios. Monitor the console for logs indicating cache hits and misses.
Contributions are welcome! Please follow these steps:
-
Fork the Repository
-
Create a Feature Branch
git checkout -b feature/my-new-feature
-
Commit Your Changes
-
Submit a Pull Request
For major changes, please open an issue first to discuss what you would like to change.
GhostCache is released under the MIT License. Feel free to use, modify, and distribute it in your projects.
GhostCache is designed to be a simple yet powerful tool for improving the performance of your web applications by reducing unnecessary network calls. With support for multiple storage adapters and both fetch()
and Axios, it adapts to a wide range of project needs.
Happy caching! 🎉