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-at-rest

v2.0.11

Published

A toolkit for building ridiculously fast web applications using React and RESTful APIs.

Readme

React-at-Rest

A toolkit for building ridiculously fast web applications using React and RESTful APIs.

Codeship Badge

Documentation

Sample Projects

Clone the react-at-rest examples repo to get started! https://github.com/PayloadDev/react-at-rest-examples

The examples project contains sample code in both ES6 and CoffeeScript.

Main Concepts

  • React-at-Rest is composed of 3 main classes, working in concert: Store, DeliveryService, and RestForm.
    • Store: manages all AJAX requests and holds the data returned by the server.
    • DeliveryService: React Component that manages and simplifies communication with the Stores.
    • RestForm: React Component for building forms and managing RESTful data flow.
  • Uses Events for Store->Component communication.
  • Written in CoffeeScript, fully compatible with ES6.
  • Uses Bootstrap classes by default, but doesn't depend on Bootstrap.
  • Uses subclasses instead of mixins or composition.
  • Plays nicely with react-router

Requirements and Installation

React-at-Rest depends on react.

npm install --save react-at-rest react

Battle Tested and Pragmatic

React-at-Rest is a collection of powerful tools that make writing SPAs faster and simpler. You'll be amazed at what you can accomplish in a very short period of time.

React-at-Rest powers the Payload SPA at payload.net.

Getting Started

You can trivially consume a RESTful API using Store and DeliveryService

ES6

class BlogPosts extends DeliveryService {

  constructor(props) {
    super(props);
    // create a new Store which connected to an API at /posts
    this.postStore = new Store('posts');
  }

  // override bindResources to load all the resources needed for this component
  bindResources(props) {
    // retrieve all the posts from the Post Store
    this.retrieveAll(this.postStore);
  }

  render() {
    // show a loading message while loading data
    if !this.state.loaded
      return (<span>Loading...</span>)

    // iterate over all the blog posts loaded from our API
    let posts = this.state.posts.map((post) => {
      return (
        <div className="panel panel-default" key={post.id}>
          <div className="panel-heading">
            <h3 className="panel-title">{post.title}</h3>
          </div>
          <div className="panel-body">
            {post.body}
          </div>
        </div>
      )

    // render the posts
    return (
      <div>
        {posts}
      </div>
    )
  }   
}

CoffeeScript

class BlogPosts extends DeliveryService

  constructor: (props) ->
    super props
    # create a new Store which connected to an API at /posts
    @postStore = new Store 'posts'


  # override bindResources to load all the resources needed for this component
  bindResources: (props) ->
    # retrieve all the posts from the Post Store
    @retrieveAll @postStore


  render: ->
    # show a loading message while loading data
    return <span>Loading...</span> unless @state.loaded

    # iterate over all the blog posts loaded from our API
    posts = for post in @state.posts
      <div className="panel panel-default" key={post.id}>
        <div className="panel-heading">
          <h3 className="panel-title">{post.title}</h3>
        </div>
        <div className="panel-body">
          {post.body}
        </div>
      </div>

    # render the posts
    <div>
      {posts}
    </div>

Or to load a single resource:

ES6

class BlogPost extends DeliveryService {

  constructor(props) {
    super(props);
    // create a new Store which connected to an API at /posts
    this.postStore = new Store('posts');
  }

  // override bindResources to load all the resources needed for this component
  bindResources(props) {
    // retrieve the post from the Post Store by id
    this.retrieveResource({this.postStore, id: this.props.postId});
  }

  render() {
    // show a loading message while loading data
    if !this.state.loaded
      return (<span>Loading...</span> )

    // render the post
    return (
      <div>
        <div className="panel panel-default">
          <div className="panel-heading">
            <h3 className="panel-title">{this.state.post.title}</h3>
          </div>
          <div className="panel-body">
            {this.state.post.body}
          </div>
        </div>
      </div>
    )
  }
}

CoffeeScript

class BlogPost extends DeliveryService

  constructor: (props) ->
    super props
    # create a new Store which connected to an API at /posts
    @postStore = new Store 'posts'


  # override bindResources to load all the resources needed for this component
  bindResources: (props) ->
    # retrieve the post from the Post Store by id
    @retrieveResource @postStore, id: @props.postId


  render: ->
    # show a loading message while loading data
    return <span>Loading...</span> unless @state.loaded

    # render the post
    <div>
      <div className="panel panel-default">
        <div className="panel-heading">
          <h3 className="panel-title">{@state.post.title}</h3>
        </div>
        <div className="panel-body">
          {@state.post.body}
        </div>
      </div>
    </div>

DeliveryService can load multiple resources in bindResources. Simply execute additional subscribeAll, subscribeResource, retrieveAll or retrieveResource methods.

Creating and updating resources

RestForm takes care of rendering create/edit forms and submitting to the API.

ES6

class BlogPostForm extends RestForm {

  //build your form using Reactified versions of regular HTML form elements
  render() {
    return (
      <form onSubmit={this.handleSubmit} className="form-horizontal">
        <Forms.TextAreaInput {...this.getFieldProps('body')}
          labelClassName='col-sm-4'
          inputWrapperClassName='col-sm-8'/>
        <Forms.TextInput {...this.getFieldProps('author')}
          labelClassName='col-sm-4'
          inputWrapperClassName='col-sm-8'/>
        <div className='text-right'>
          <button className='btn btn-primary'>Create Post</button>
        </div>
      </form>
    )
  }
}

CoffeeScript

class BlogPostForm extends RestForm

  # build your form using Reactified versions of regular HTML form elements
  render: ->
    <form onSubmit={@handleSubmit} className="form-horizontal">
      <Forms.TextAreaInput {...@getFieldProps('body')}
        labelClassName='col-sm-4'
        inputWrapperClassName='col-sm-8'/>
      <Forms.TextInput {...@getFieldProps('author')}
        labelClassName='col-sm-4'
        inputWrapperClassName='col-sm-8'/>
      <div className='text-right'>
        <button className='btn btn-primary'>Create Post</button>
      </div>
    </form>

Then render your form component with either a blank model, or one retrieved from the API

ES6

// in <BlogPosts /> component
<BlogPostForm model={{}} store={this.postStore} />

// or to edit a blog posted loaded in a DeliveryService subclass
<BlogPostForm model={this.state.post} store={this.postStore} />

CoffeeScript

# in <BlogPosts /> component
<BlogPostForm model={{}} store={@postStore} />

# or to edit a blog posted loaded in a DeliveryService subclass
<BlogPostForm model={@state.post} store={@postStore} />

Credits

React-at-Rest was developed by the team at Payload and maintained by Ben Sargent.

Event code from the Backbone project.