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 🙏

© 2025 – Pkg Stats / Ryan Hefner

immreact

v0.2.0

Published

Use react classes with an immstruct structure

Readme

immreact

Centralised immutable data structure designed for use with React

Standing on the shoulders of the immstruct and immutable teams.

Getting Started

npm i -S immreact

To use the library, include it and then create an instance of a state structure

import Immreact from 'immreact'

let state = new Immreact.State()

Immreact enforces top-down rendering through update events emitted by the state tree when mutations occur, but the choice of how to structure your app is still in your hands.

Example with stateless components

Presentational and business logic can be entirely decoupled by use of the state dispatcher. The dispatcher used is the same one from Flux and responses occur by registering callbacks.

import Immreact from 'immreact'

let state = new Immreact.State()

state.register( dispatch => {
  // Respond to dispatches and perform actions
})

const App = props => {
  return (
    <button
      onClick={ event => {
        state.dispatch({
          type: 'dispatchedEventType',
          payload: { ... }
        })
      }}
    >Click me</button>
  )
}

This pattern scales well and allows action objects to attach callbacks to the state tree which respond to dispatches triggered from your UI.

Immreact.State exposes two methods for accessing the state tree, cursor and get. Both methods have the same signature which accepts an array of strings describing a key path to access the tree and return either a cursor to the data or a read-only instance of an unwrapped cursor. This equates to either a cursor which can be updated or the data itself.

Presentational components should be passed dereferenced data in order to render themselves whilst the application logic should access cursors to allow data updates to occur.

import Immreact from 'immreact'
import React from 'react'
import ReactDOM from 'react-dom'

// Set up the initial state of the application
let state = new Immreact.State( 'app', {
  count: 0
})

state.register( dispatch => {
  if ( dispatch.type === 'incrementCounter' ) {
    state.cursor([ 'app', 'count' ]).update( cursor => ++cursor )
    return
  }
})

const App = props => {
  return (
    <div>
      <h1>Counter <span>{ props.state.get( 'count' ) }</span></h1>
      <button
        onClick={ event => {
          state.dispatch({
            type: 'incrementCounter'
          })
        }}
      >Increment</button>
    </div>
  )
}

// Pass only dereferenced data to the presentational components
// `State.get` will also accept a string for top-level structures
function render( appstate ) {
  ReactDOM.render( <App state={ appstate.get( 'app' ) } />, document.body )
}

// Re-render on update events
// Update event pass the state tree to the update callback
// 'State.start' simply fires an update to render the initial application state
state
  .on( 'update', render )
  .start()

Example with stateful-like components

Cursors or references can be passed directly to components to simulate internal component state. Passing references means that child component must grab their own cursors but cursors from references will be fresh. They can be passed down the render tree to children or grabbed directly from the state object by using a key path.

import Immreact from 'immreact'
import React from 'react'
import ReactDOM from 'react-dom'

let state = new Immreact.State( 'app', {
  count: 0
})

const App = props => {
  return (
    <div>
      <h1>Counter <span>{ props.state.cursor( 'count' ).deref() }</span></h1>
      <button
        onClick={ event => {
          props.state.cursor( 'count' ).update( cursor => ++cursor )
        }}
      >Increment</button>
    </div>
  )
}

// Pass a cursor in to the stateful-like components
function render( appstate ) {
  ReactDOM.render( <App state={ appstate.reference( 'app' ) } />, document.body )
}

state
  .on( 'update', render )
  .start()

Running the examples

Once you’ve cloned and installed all the dependencies you use can use npm to spawn a server to show some example usage of immreact

npm start -- -o

The examples server will watch for changes to the library and reload so feel free to also fire the watch script and hack on the code too

npm run watch

Contributing

PR’s are welcome, feel free to open an issue first to discuss if necessary.

In lieu of a formal styleguide please try to follow the style of the existing codebase, create new tests for all new functionality and ensure all tests are passing.

To build the project use

npm run build

There is also a watch script

npm run watch

If you’re running the examples server then that will listen for changes to the code and reload, use the following commands to fire up the examples server and the watch task

npm start
npm run watch

Install

Using npm,

npm install --save immreact

License

ISC