@resilient

Getting Started

Get up and running with @resilient in just a few minutes.

Installation

npm install react-resilient-hooks

Or with yarn: yarn add react-resilient-hooks

Quick Start

No configuration needed. Just import and use the hooks directly in your components:

import { useNetworkStatus, useAdaptiveImage } from 'react-resilient-hooks';

function MyComponent() {
  const { data: network } = useNetworkStatus();

  const imageUrl = useAdaptiveImage({
    low: '/images/hero-small.jpg',
    medium: '/images/hero-medium.jpg',
    high: '/images/hero-large.jpg',
  });

  return (
    <div>
      <p>Connection: {network?.effectiveType || 'Unknown'}</p>
      <img src={imageUrl} alt="Adaptive hero" />
    </div>
  );
}

Common Use Cases

1. Adaptive Image Loading

Serve different image qualities based on network speed:

import { useAdaptiveImage } from 'react-resilient-hooks';

function ProductImage({ product }) {
  const src = useAdaptiveImage({
    low: product.thumbnail,    // 150px - for 2G
    medium: product.image,     // 300px - for 3G
    high: product.largeImage,  // 600px - for 4G/WiFi
  });

  return <img src={src} alt={product.name} />;
}

2. Connection-Aware Polling

Poll for updates less frequently on slow networks:

import { useAdaptivePolling } from 'react-resilient-hooks';

function LivePrices() {
  const [prices, setPrices] = useState([]);

  const fetchPrices = async () => {
    const res = await fetch('/api/prices');
    setPrices(await res.json());
  };

  // Polls every 5s on 4G, 10s on 3G, 15s on 2G
  // Automatically pauses when offline
  useAdaptivePolling(fetchPrices, {
    baseInterval: 5000,
    pauseWhenOffline: true,
  });

  return <PriceList prices={prices} />;
}

3. Offline Form Submission

Queue form submissions while offline, sync when back online:

import { useBackgroundSync } from 'react-resilient-hooks';

function CommentForm() {
  const { enqueue, isFlushing, queueSize } = useBackgroundSync({
    onSuccess: (req) => toast.success('Comment posted!'),
    onError: (req, err) => toast.error('Failed to post comment'),
  });

  const handleSubmit = async (e) => {
    e.preventDefault();
    const formData = new FormData(e.target);

    await enqueue({
      id: crypto.randomUUID(),
      url: '/api/comments',
      options: {
        method: 'POST',
        body: JSON.stringify(Object.fromEntries(formData)),
      },
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <textarea name="comment" />
      <button type="submit">
        Post {queueSize > 0 && `(${queueSize} pending)`}
      </button>
    </form>
  );
}

TypeScript Support

All hooks come with full TypeScript support out of the box:

import type { NetworkStatus } from 'react-resilient-hooks';

// NetworkStatus type includes:
interface NetworkStatus {
  online: boolean;
  effectiveType?: 'slow-2g' | '2g' | '3g' | '4g';
  downlink?: number;
  rtt?: number;
  saveData?: boolean;
}

Next Steps