npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pawells/react-graphql

v2.1.1

Published

React runtime companion providing Apollo Client setup, connection state management, and GraphQLProvider

Readme

React GraphQL Client

GitHub Release CI npm version Node License: MIT GitHub Sponsors

Installation

yarn add @pawells/react-graphql @apollo/client graphql graphql-ws

Requirements

Peer dependencies that must be present in your project:

  • @apollo/client >=4.0.0
  • graphql >=16.0.0
  • react >=18.0.0
  • rxjs >=7.0.0

The graphql-ws package is bundled as a runtime dependency.

Quick Start

import { GraphQLProvider } from '@pawells/react-graphql';
import App from './App';

export default function Root() {
  return (
    <GraphQLProvider
      options={{
        name: 'my-app',
        httpUri: 'http://localhost:4000/graphql',
        wsUri: 'ws://localhost:4000/graphql',
      }}
    >
      <App />
    </GraphQLProvider>
  );
}

Features

  • Apollo Client Setup — Preconfigured with HTTP and WebSocket links
  • Connection State Management — Track connection status (Connecting, Connected, Reconnecting, Disconnected, Error)
  • Auto-retry with Exponential Backoff — Handles network failures gracefully
  • Token-based Authentication — Support for static and dynamic JWT tokens
  • WebSocket Subscriptions — Built-in support for GraphQL subscriptions via graphql-ws
  • Error Logging — Optional logging for GraphQL and network errors
  • Custom Cache — Use your own Apollo InMemoryCache or let us create one

API

GraphQLProvider

Wraps your app with Apollo Client and connection state context.

<GraphQLProvider
  options={{
    name: 'my-app',
    httpUri: 'http://localhost:4000/graphql',
    wsUri: 'ws://localhost:4000/graphql',
    token: () => localStorage.getItem('auth_token'),
    logGraphQLErrors: true,
    logNetworkErrors: true,
  }}
  fallback={<LoadingSpinner />}
>
  <YourApp />
</GraphQLProvider>

useConnectionState

Returns the current GraphQL connection state.

import { useConnectionState, GraphQLConnectionState } from '@pawells/react-graphql';

function Header() {
  const state = useConnectionState();
  
  return (
    <div>
      Status: {state}
      {state === GraphQLConnectionState.Disconnected && (
        <span className="error">Connection lost</span>
      )}
    </div>
  );
}

useGraphQLReconnect

Manually trigger a reconnection.

import { useGraphQLReconnect } from '@pawells/react-graphql';

function ConnectionControl() {
  const reconnect = useGraphQLReconnect();
  
  return <button onClick={reconnect}>Reconnect</button>;
}

useGraphQLContext

Low-level hook that returns the full GraphQLContext value containing both connectionState and reconnect. Use this when you need both values in the same component and want to avoid two separate hook calls. Throws if called outside a GraphQLProvider.

import { useGraphQLContext, GraphQLConnectionState } from '@pawells/react-graphql';

function ConnectionBanner() {
  const { connectionState, reconnect } = useGraphQLContext();

  if (connectionState === GraphQLConnectionState.Error) {
    return (
      <div className="banner error">
        Connection error. <button onClick={reconnect}>Retry</button>
      </div>
    );
  }

  return null;
}

useConnectionState() and useGraphQLReconnect() are thin wrappers around useGraphQLContext() — prefer those for single-value access.

Connection States

  • Connecting — Initial connection attempt or explicit reconnection
  • Connected — Successfully connected to GraphQL server
  • Reconnecting — Automatic reconnection after losing connection
  • Disconnected — Connection closed normally
  • Error — Connection error occurred

Advanced Usage

Custom Error Handling

Implement detailed error handling for GraphQL and network errors:

import { GraphQLProvider } from '@pawells/react-graphql';

function CustomErrorHandler() {
  const handleErrors = {
    logGraphQLErrors: true,
    logNetworkErrors: true,
  };

  return (
    <GraphQLProvider
      options={{
        name: 'my-app',
        httpUri: 'http://localhost:4000/graphql',
        wsUri: 'ws://localhost:4000/graphql',
        ...handleErrors,
      }}
    >
      <App />
    </GraphQLProvider>
  );
}

With custom logging, errors are logged to the console before being passed to your error handlers. Differentiate between GraphQL errors (resolver failures) and network errors (connection issues):

// In your client-side error handling
import { GraphQLError } from 'graphql';

function handleGraphQLError(error: GraphQLError) {
  const code = error.extensions?.code;
  const statusCode = error.extensions?.statusCode;
  
  if (statusCode === 401) {
    // Handle unauthorized — refresh token or redirect to login
  } else if (statusCode === 403) {
    // Handle forbidden — show permission error
  }
}

Token Refresh Strategies

Implement dynamic token refresh on each request:

import { GraphQLProvider } from '@pawells/react-graphql';

function TokenManager() {
  const getToken = async () => {
    // Check if token is expired
    const token = localStorage.getItem('auth_token');
    const expiresAt = localStorage.getItem('token_expires_at');
    
    if (expiresAt && Date.now() >= parseInt(expiresAt)) {
      // Refresh token
      const response = await fetch('/api/refresh', {
        method: 'POST',
        credentials: 'include',
      });
      const { token: newToken, expiresIn } = await response.json();
      localStorage.setItem('auth_token', newToken);
      localStorage.setItem('token_expires_at', Date.now() + expiresIn * 1000);
      return newToken;
    }
    
    return token;
  };

  return (
    <GraphQLProvider
      options={{
        name: 'my-app',
        httpUri: 'http://localhost:4000/graphql',
        wsUri: 'ws://localhost:4000/graphql',
        token: getToken, // Function called on each request
      }}
    >
      <App />
    </GraphQLProvider>
  );
}

Custom Apollo Cache Configuration

Use a custom InMemoryCache for advanced caching strategies:

import { GraphQLProvider } from '@pawells/react-graphql';
import { InMemoryCache, possibleTypesResult } from '@apollo/client';

function CacheConfiguration() {
  const cache = new InMemoryCache({
    possibleTypes: possibleTypesResult.possibleTypes,
    typePolicies: {
      Query: {
        fields: {
          user: {
            read(existing, { args, toReference }) {
              // Custom read policy for user queries
              return existing || toReference({ __typename: 'User', id: args.id });
            },
          },
        },
      },
      User: {
        keyFields: ['id'],
        fields: {
          posts: {
            merge(existing = [], incoming) {
              // Merge new posts with existing
              return [...existing, ...incoming];
            },
          },
        },
      },
    },
  });

  return (
    <GraphQLProvider
      options={{
        name: 'my-app',
        httpUri: 'http://localhost:4000/graphql',
        wsUri: 'ws://localhost:4000/graphql',
        cache,
      }}
    >
      <App />
    </GraphQLProvider>
  );
}

Connection State Monitoring

Monitor detailed connection state changes and react to them:

import { useConnectionState, GraphQLConnectionState, useGraphQLReconnect } from '@pawells/react-graphql';
import { useEffect } from 'react';

function ConnectionMonitor() {
  const state = useConnectionState();
  const reconnect = useGraphQLReconnect();

  useEffect(() => {
    if (state === GraphQLConnectionState.Error) {
      // Automatically reconnect on error after 5 seconds
      const timer = setTimeout(() => reconnect(), 5000);
      return () => clearTimeout(timer);
    }
  }, [state, reconnect]);

  useEffect(() => {
    const logConnection = () => {
      console.log(`GraphQL connection: ${state}`);
      
      switch (state) {
        case GraphQLConnectionState.Connecting:
          console.log('Attempting to connect...');
          break;
        case GraphQLConnectionState.Connected:
          console.log('Connected to GraphQL server');
          break;
        case GraphQLConnectionState.Reconnecting:
          console.log('Reconnecting after connection loss...');
          break;
        case GraphQLConnectionState.Disconnected:
          console.log('Disconnected from server');
          break;
        case GraphQLConnectionState.Error:
          console.error('Connection error occurred');
          break;
      }
    };

    logConnection();
  }, [state]);

  return (
    <div className={`connection-status ${state.toLowerCase()}`}>
      Status: {state}
    </div>
  );
}

License

MIT