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

react-apollo-helpers

v0.1.2

Published

An alternate api for react-apollo with helpful defaults and less boilerplate.

Readme

react-apollo-helpers

Work in progress. API is subject to change.

Provides a thin wrapper for react-apollo's graphql() and other convenience functions to explore some possibilities for simplifying its API. Instead of this:

const CommentPageWithData = graphql(submitComment, {
  props: ({ ownProps, mutate }) => ({
    submit: ({ repoFullName, commentContent }) => mutate({
      variables: { repoFullName, commentContent },
      optimisticResponse: {
        __typename: 'Mutation',
        submitComment: {
          __typename: 'Comment',
          postedBy: ownProps.currentUser,
          createdAt: +new Date,
          content: commentContent,
        },
      },
    }),
  }),
})(CommentPage);

Use this:

const CommentPageWithData = graphql(submitComment, {
  options: {
    optimisticResponse: ({ commentContent }, ownProps) => ({
      __typename: 'Comment',
      postedBy: ownProps.currentUser,
      createdAt: +new Date,
      content: commentContent,
    }),
  },
})(CommentPage);

See the react-apollo docs for more details on the context/use of this function. It still calls react-apollo under the hood – this is purely an API experiment.

(Disclaimer: the above code would need to use name: 'submit' to be 100% backwards compatible with the example in the react-apollo docs, but in practice you could avoid this by making the prop name in the presentational component match the query's operation name)

Features

  • Works like the current graphql(), but with less code.
  • Intelligent but overridable default names for your query and mutation propnames.
  • Prop naming works the same for queries and mutations
  • Intuitive mutations:
    • variables will default to the arguments specified by your mutation document. You no longer have to specify them in most cases.
    • optimisticResponse can take a function and allows you to return only the type you are returning (omitting the enclosing type Mutation).
    • still compatible with normal react-apollo syntax if you need/prefer it for certain mutations – just specify props. This will override defaults provided by this module. Subscriptions currently pass-through unchanged. (see react-apollo docs for usage)

Basic Usage

Add react-apollo and react-apollo-helpers to your package.json:

  • npm install --save react-apollo react-apollo-helpers

Run locally:

  • clone this repo and get the path with pwd
  • go to your app directory
  • run npm link path/to/react-apollo-helpers

In your app:

import gql from 'graphql-tag';
import { graphql, optimisticResponse } from 'react-apollo-helpers';
// optional, but recommmended:
import { compose } from 'recompose';

Specify a query:

const getTodos = graphql(gql`
  query getTodos {
    todos {
      goal
    }
  }`,
  {
    // name defaults to `getTodos` – or pass `name: 'myQuery',` to set manually
    options: { /* apollo-client watchQuery options */ },
  },
);

Specify a mutation (variables and prop name will be set based on the document):

const createTodo = graphql(gql`
  mutation createTodo ($goal: String!){
    createTodo (
      goal: $goal
    ) {
      goal
    }
  }`,
  {
    options: { /* apollo-client mutate options */ },
  }
);

Make a presentational component that will consume the graphql operations:

const Todos = ({ getTodos: { todos }, createTodo }) => (
  <div>
    <form
      onSubmit={e => {
        e.preventDefault();
        createTodo({ goal: e.currentTarget.goal.value });
      }}
    >
      <input
        type="text"
        id="goal"
        placeholder="Add a todo"
      />
    </form>

    <ul>
      {
        todos.map(todo => (
          <li> {todo.goal} </li>
        ))
      }
    </ul>
  </div>
);

Compose the query and mutation together with the presentational component:

export default compose(todosQuery, createTodo)(Todos);

Prop name passed to the presentational component

graphql() creates a higher-order component (HOC) that will add a single property to your presentational component when composed with it. That prop will have either the query results or will be a function you can call to perform its mutation. You can compose multiple graphQL operations (and other non-graphQL HOCs) together on one presentational component with compose() as shown above. The name of the prop that will be handed down to your presentational component will be set in one of 3 ways, with preference going to 1 before 2 before 3.

  1. name property: graphql(gql..., {name: 'myProp'}). Unlike basic react-apollo, you can set this for mutations as well as queries. Overrides any defaults.
  2. operation name (see below). This is the name you use for updateQueries and is also sent to the server so you can tell what queries came from where.
  3. query/mutation name (see below). This is the name in your main graphQL schema, which matches a resolver of the same name on the server.
const getTodos = graphql(gql`
  query getTodos {  <--- 2. operation name: `getTodos`
    todos {         <--- 3. query name: `todos`
      goal
    }
  }`
);

Generally, you will want to use the operation name (2). Although it can seem redundant with the schema query name in trivial examples, in a real app you may query the same base query differently (different result sets, pagination, filters, etc.).

optimisticResponse

For mutations, the optimisticResponse and variables objects can take a function that receives (args, ownProps):

...
  options: {
    optimisticResponse: ({ goal }, ownProps) => ({
      __typename: 'Mutation',
      createTodo: {
        __typename: 'Todo',
        id: Math.random().toString(),
        goal,
      },
    }),
  },

or you can omit the first layer of the optimisticResponse object:

...
  options: {
    optimisticResponse: ({ goal }, ownProps) => ({
      __typename: 'Todo',
      id: Math.random().toString(),
      goal,
    }),
  },

or you can specify just the fields you need to add with the optimisticResponse() function:

import { graphql, optimisticResponse } from 'react-apollo-helpers';

...
  options: {
    optimisticResponse: optimisticResponse({
      __typename: 'Todo', // still required: use the mutation return type 
      _id: `${Random.id()}`, // add fields you need to generate
      // don't need to add goal; it will be added automatically
    }),
  },

updateQueries

There is no change to how updateQueries works.

Todo:

  • [x] remove composition and rename function (use recompose instead)
  • [x] probably change operation spec api to match apollo-client
  • [x] possibly set default query response prop (currently data)
  • [x] simplify optimisticResponse with good defaults from document/schema
  • [ ] add some common reducers for use in updateQueries
  • [ ] possible improvements for subscriptions (currently passes through unchanged, so they should work the same here as in regular react-apollo)

Why not just do a PR against react-apollo?

Setting default prop names would be a breaking change, so let's prove in the concept here and see if people like it. If all of this ends up in react-apollo, that'd be awesome :) Then we would just deprecate this module.

Testing

Needs tests.

Thanks

  • @jamielob for the initial inspiration
  • @ecwyne for code improvements and ideas