• This repository has been archived on 14/Feb/2023
  • Stars
    star
    1,908
  • Rank 24,300 (Top 0.5 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created about 6 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

React, but with built-in global state management.

ReactN

Tweet version minzipped size downloads

ReactN is an extension of React that includes global state management. It treats global state as if it were built into React itself -- without the boilerplate of third party libraries.

banner

For support, reach out to us on the Reactiflux Discord channel #reactn.

💗 this project? Become a sponsor.

Install

  • npm install reactn or
  • yarn add reactn

Features

No boilerplate

For function components, import { useGlobal } from "reactn"; to harness the power of React Hooks!

For class components, simply change import React from "react"; to import React from "reactn";, and your React class components will have global state built in!

If you prefer class decorators, you can continue to import React from "react"; for your components and additionally import reactn from "reactn"; for access to the @reactn decorator!

Intuitive

Function components

Global state in function components behaves almost identically to local state.

You use [ global, setGlobal ] = useGlobal() to access the entire global state object.

You use [ value, setValue ] = useGlobal(property) where property is the property of the global state you want to get and set.

Global reducers in function components behaves almost identically to local reducers.

You use dispatch = useDispatch(reducerFunction) to mimic the behavior of useReducer, where instead of providing an initial state, the state of the reducer is the ReactN global state object.

You use dispatch = useDispatch(reducerName) to use a reducer that was added by the addReducer helper function.

You use dispatch = useDispatch(reducerFunction, property) or [ value, dispatch ] = useDispatch(reducerFunction, property) to apply a reducer specifically to a global state property. This is very similar to React's native useReducer functionality.

Class components

Global state in class components behaves exactly like local state!

You use this.global and this.setGlobal to get and set the global state.

You use this.dispatch.reducerName() to dispatch to a reducer that was added by the addReducer helper function.

The @reactn decorator allows you to convert classes that extend React.Component to ReactN global state components.

Map state to props

If you prefer Redux's connect functionality, pure functions, or are dealing with deeply nested objects, a withGlobal higher-order component is also available.

Table of contents

Getting started

Managing multiple states

This README is for managing a single global state. This is ideal for most applications. If you are using concurrent server-side rendering or otherwise want to work with multiple global states, follow the README for the Provider component, which allows you to limit a ReactN state to a React Context.

If you are unsure whether or not you need multiple global states, then you do not need multiple global states.

Initializing your state

You can initialize your global state using the setGlobal helper function. In most cases, you do not want to initialize your global state in a component lifecycle method, as the global state should exist before your components attempt to render.

It is recommended that you initialize the global state just prior to mounting with ReactDOM.

import React, { setGlobal } from 'reactn';
import ReactDOM from 'react-dom';
import App from './App';

// Set an initial global state directly:
setGlobal({
  cards: [],
  disabled: false,
  initial: 'values',
  x: 1,
});

ReactDOM.render(<App />, document.getElementById('root'));

TypeScript support

ReactN supports TypeScript out of the box! It is written entirely in TypeScript. This gives it powerful intellisense, auto-complete, and error-catching abilities.

TypeScript can maintain inferred global state and reducer shape of a Providers. Unfortunately, without your help, it cannot track the shape of the "default" global state -- the one manipulated by the setGlobal and addReducer helper functions.

In order to tell TypeScript the shape of your global state when you are not using a Provider, create a file at src/global.d.ts with the following contents:

import "reactn";

declare module "reactn/default" {

  export interface Reducers {

    append: (
      global: State,
      dispatch: Dispatch,
      ...strings: any[]
    ) => Pick<State, "value">;

    increment: (
      global: State,
      dispatch: Dispatch,
      i: number,
    ) => Pick<State, "count">;

    doNothing: (
      global: State,
      dispatch: Dispatch,
    ) => null;
  }

  export interface State {
    count: number;
    value: string;
  }
}

In the above file, we extend the Reducers and State interfaces in the "reactn/default" file. While you will never use "reactn/default" in your code, ReactN will use it to determine the shape of the default global state.

The above example will add append, increment, and doNothing to your useDispatch and this.dispatch auto-completion and typing. The parameters and return values will also be correctly typed. In addition, it will also add count and value to your useGlobal and this.global auto-competion with the appropriate types as well.

Developer tools

ReactN is compatible with the Redux DevTools extension.

  • Install the Redux DevTools extension to your browser or environment.
  • Install the redux package to your project via npm or yarn. This is used to create a middleware Redux store for the Redux DevTools extension.
    • You do not have to import or use the redux package anywhere in your project.
    • You do not need to create a Redux store, reducer, or actions.
    • redux is just a peer dependency. It will be managed automatically.
  • Follow the instructions on the ReactN DevTools README.

Examples

Class components

By importing React from reactn instead of react, you bake global state directly into the React namespace. As a result, Component and PureComponent will have access to the global and dispatch member variables and setGlobal method.

import React from 'reactn'; // <-- reactn
import Card from '../card/card';

// Render all cards in the global state.
export default class Cards extends React.PureComponent {
  componentDidMount() {
    // Hydrate the global state with the response from /api/cards.
    this.setGlobal(
      // Despite fetch returning a Promise, ReactN can handle it.
      fetch('/api/cards')
        .then((response) => response.json())

        // Set the global `cards` property to the response.
        .then((cards) => ({ cards }))

        // Fail gracefully, set the global `error`
        //   property to the caught error.
        .catch((err) => ({ error: err }))
    );
  }

  render() {
    // For each card in the global state, render a Card component.
    // this.global returns the global state,
    //   much the same way this.state returns the local state.
    return (
      <div>
        {this.global.cards.map((card) => (
          <Card key={card.id} {...card} />
        ))}
      </div>
    );
  }
}

Class components (with decorator)

By importing React and ReactN separately, the React namespace remains unchanged. You can inject ReactN's global functionality into your vanilla React component by using the @reactn decorator imported from the reactn package.

import React from 'react';
import reactn from 'reactn'; // <-- reactn
import Card from '../card/card';

// Render all cards in the global state.
@reactn
export default class Cards extends React.PureComponent {
  componentDidMount() {
    // Hydrate the global state with the response from /api/cards.
    this.setGlobal(
      // Despite fetch returning a Promise, ReactN can handle it.
      fetch('/api/cards')
        .then((response) => response.json())

        // Set the global `cards` property to the response.
        .then((cards) => ({ cards }))

        // Fail gracefully, set the global `error`
        //   property to the caught error.
        .catch((err) => ({ error: err }))
    );
  }

  render() {
    // For each card in the global state, render a Card component.
    // this.global returns the global state,
    //   much the same way this.state returns the local state.
    return (
      <div>
        {this.global.cards.map((card) => (
          <Card key={card.id} {...card} />
        ))}
      </div>
    );
  }
}

Function components

Using React Hooks, you can harness useGlobal to access the global state.

import React, { useGlobal } from 'reactn'; // <-- reactn
import Card from '../card/card';

// Render all cards in the global state.
const Cards = () => {
  // Use the hook to get all cards in the global state.
  //   setCards is not used in this example.
  const [cards, setCards] = useGlobal('cards');

  // For each card in the global state, render a Card component.
  return (
    <div>
      {cards.map((card) => (
        <Card key={card.id} {...card} />
      ))}
    </div>
  );
};

export default Cards;

You may also use the useDispatch hook analogously to the useReducer hook by providing a function to useDispatch.

import React, { useDispatch } from 'reactn'; // <-- reactn

const incrementReducer = (global, dispatch, action) => ({
  count: global.count + action.amount,
});

const decrementReducer = (global, dispatch, action) => ({
  count: global.count - action.amount,
});

const MyComponent = () => {
  const increment = useDispatch(incrementReducer);
  const decrement = useDispatch(decrementReducer);

  return (
    <div>
      <button onClick={() => increment({ amount: 1 })}>Add 1</button>
      <button onClick={() => increment({ amount: 3 })}>Add 3</button>
      <button onClick={() => decrement({ amount: 5 })}>Subtract 5</button>
    </div>
  );
};

export default MyComponent;

By providing a second parameter to useDispatch that is the key of the global state, the return value of that reducer will set that property of the global state. This allows you to write your reducers similar to React's useReducer.

import React, { useDispatch } from 'reactn'; // <-- reactn

const incrementReducer = (count, action) => count + action.amount;

const decrementReducer = (count, action) => count - action.amount;

const MyComponent = () => {
  const increment = useDispatch(incrementReducer, 'count');
  const decrement = useDispatch(decrementReducer, 'count');

  return (
    <div>
      <button onClick={() => increment({ amount: 1 })}>Add 1</button>
      <button onClick={() => increment({ amount: 3 })}>Add 3</button>
      <button onClick={() => decrement({ amount: 5 })}>Subtract 5</button>
    </div>
  );
};

export default MyComponent;

Helper functions

addCallback

Use addCallback to execute a function whenever the state changes. The return value of the callback will update the global state, so be sure to only return undefined or null if you do not want the global state to change. Be aware that always returning a new state value will result in an infinite loop, as the new global state will trigger the very same callback.

The only parameter is the callback function.

import { addCallback, setGlobal } from 'reactn';

// Every time the global state changes, this function will execute.
addCallback((global, dispatcherMap, stateChange) => {
  alert(`The new value is ${global.value}!`);

  // If the global state was changed to 1, change it to 2.
  if (global.value === 1) {
    return { value: 2 };
  }

  // If the global state is anything other than 1, don't change it.
  return null;
});

setGlobal({ value: 1 });
// The new value is 1!
// The new value is 2!

The return value of addCallback is a function that, when executed, removes the callback.

import { addCallback, setGlobal } from 'reactn';

const removeAlert = addCallback((global) => {
  alert(global.value);
});

// The callback causes an alert on global state change:
setGlobal({ value: 1 }); // 1
setGlobal({ value: 2 }); // 2

// No longer execute the callback.
removeAlert();

// No alerts:
setGlobal({ value: 3 });
setGlobal({ value: 4 });
addReducer

Use addReducer to add a reducer to your global state.

The first parameter is the name of your reducer. You will access your reducer by this name. this.dispatch.reducerName or useDispatch("reducerName").

The second parameter is the reducer function. The reducer function that you write has at least two parameters: first, the global state; second, a map of your reducers. The third and onward parameters are the arguments that you pass when dispatching. The reducer function that you use when dispatching does not contain the global state or map of reducers. Those are prefixed for you automatically.

import { addReducer, setGlobal, useDispatch, useGlobal } from 'reactn';

// Initialize the global state with the value 0.
setGlobal({ value: 0 });

// When the increment reducer is called, increment the global value by X.
addReducer('increment', (global, dispatch, x = 1) => ({
  value: global.value + x,
}));

function MyComponent() {
  const increment = useDispatch('increment');
  const [value] = useGlobal('value');
  return (
    <>
      The value is{' '}
      <button
        onClick={() => {
          // Increment from 0 to 1.
          // (the default value of the reducer is 1)
          if (value === 0) {
            increment();
          }

          // Increment from 1 to 5.
          else if (value === 1) {
            increment(4);
          }
        }}
        value={value}
      />
    </>
  );
}

For a class component, the analogous method is this.dispatch.increment(value).

The dispatch parameter on a reducer allows you to write "sagas," or a single reducer that dispatches other reducers.

// add(1)
addReducer('add', (global, dispatch, i) => ({
  x: global.x + i,
}));

// subtract(2)
addReducer('subtract', (global, dispatch, i) => ({
  x: global.x - i,
}));

// addSubtract(1, 2)
addReducer('addSubtract', async (global, dispatch, i, j) => {
  await dispatch.add(i);
  await dispatch.subtract(j);
});
addReducers

addReducers accepts an object where the keys are reducer names and the values are reducers. addReducers is just a convenient shorthand for calling addReducer multiple times.

getDispatch

Use getDispatch to return an object of the global dispatch functions. You only want to use this in helper libraries, and not in Components. Components should use useDispatch or this.dispatch.

getDispatch has no parameters.

import { getDispatch } from 'reactn';

// Access this.dispatch.reducerName outside of a Component.
class HelperLibrary {
  getDispatcherFunction() {
    return getDispatch().reducerName;
  }
}
getGlobal

Use getGlobal to return a current snapshot of the global state. You only want to use this in helper libraries, and not in Components. Components should use useGlobal or this.global to ensure that they re-render when the global state changes. getGlobal will not cause a Component reliant on the global state to re-render, nor will it cause a library function to re-execute. It does nothing more than return a current snapshot of the global state.

getGlobal has no parameters.

import { getGlobal } from 'reactn';

// Access this.global.value outside of a Component.
class HelperLibrary {
  getGlobalValue() {
    return getGlobal().value;
  }
}
removeCallback

Use removeCallback to remove a callback that was added via addCallback. The callback must be the same function reference. This is equivalent to executing the return value of addCallback.

The only parameter is the callback function itself.

import { addCallback, removeCallback, setGlobal } from 'reactn';

function alertCallback(global) {
  alert(global.value);
}

addCallback(alertCallback);

// Alerts the global state value:
setGlobal({ value: 1 }); // 1
setGlobal({ value: 2 }); // 2

// Remove the alert callback:
removeCallback(alertCallback);

// No alerts:
setGlobal({ value: 3 });
setGlobal({ value: 4 });
resetGlobal

Use resetGlobal to reset the global state. This resets all state values, including callbacks, property listeners, and reducers.

There are no parameters.

import { getGlobal, resetGlobal, setGlobal } from 'reactn';

// Set the value.
setGlobal({ value: 1 });

// Get the value.
alert(getGlobal().value); // 1

// Reset the global state.
resetGlobal();

// Get the value.
alert(getGlobal().value); // undefined
setGlobal

Use setGlobal to initialize or update your global state. This is analogous to calling this.setGlobal in a class component or useGlobal()[1] in a function component.

The first parameter is merged into the global state in the same way a class component's this.setGlobal merges its first parameter into the local state.

The optional second parameter is a callback.

setGlobal with a new global state:

import { setGlobal } from 'reactn';

// Set loading to true.
setGlobal({
  loading: true,
});

setGlobal with a new global state and a callback:

import { setGlobal } from 'reactn';

// Set loading to true.
setGlobal(
  {
    loading: true,
  },

  // After it is set, assert that loading is true.
  (global) => {
    assert(global.loading === true);
  }
);
useDispatch

Requires React >= 16.8.0

The useDispatch helper function is a React Hook analogous to the useReducer hook built into React itself. useDispatch will dispatch a global reducer that has been added to ReactN via the addReducer, addReducers, or withInit helper functions or a global reducer that you specify inline as a parameter.

useDispatch()

useDispatch() with no parameters will return a map of all of your global reducers.

import { useDispatch } from 'reactn';

function MyComponent() {
  const dispatch = useDispatch();
  dispatch.add(1);
  dispatch.substract(2);
  return null;
}
useDispatch(Function)

useDispatch(f) allows you to define your global reducer inline. This method is particularly useful if you prefer to import your reducers as needed or keep your singleton reducers with the components that use them.

import React, { useDispatch, useGlobal } from 'reactn';

function MyComponent() {
  const [count] = useGlobal('count');
  const add = useDispatch((global, _dispatch, n) => ({
    count: global.count + n,
  }));
  return <button onClick={() => add(1)}>{count}.</span>;
}
useDispatch(Function, keyof State)

useDispatch(f, "property") allows you to define your global property reducer inline. A property reducer changes only one property of the global state, which can greatly simplify your reducer logic.

import React, { useDispatch, useGlobal } from 'reactn';

function MyComponent() {
  const [count] = useGlobal('count');
  const add = useDispatch((count, n) => count + n, 'count');
  return <button onClick={() => add(1)}>{count}.</span>;
}
useDispatch(keyof Reducers)

useDispatch("reducerName") allows you to dispatch a global reducer.

import React, { useDispatch, useGlobal } from 'reactn';

function MyComponent() {
  const [count] = useGlobal('count');
  const add = useDispatch('add');
  return <button onClick={() => add(1)}>{count}.</span>;
}
useGlobal

Requires React >= 16.8.0

useGlobal is a React Hook analogous to the useState Hook built into React itself. useGlobal returns the global state or parts thereof.

useGlobal()

useGlobal() with no parameters will return the entire global state object and a function for changing properties of the global state.

The setGlobal function returned by useGlobal is analogous to the setGlobal helper function and this.setGlobal class method.

import React, { useGlobal } from "reactn";

function MyComponent() {
  const [ global, setGlobal ] = useGlobal();
  const generateNumber = () => {
    setGlobal(g => ({
      generations: g.generations + 1,
      myNumber: Math.floor(Math.random() * 100),
    });
  };
  return (
    <button onClick={generateNumber}>
      #{global.generations}: {global.myNumber}
    </button>
  );
}
useGlobal(keyof State)

useGlobal("property") returns a specific global state property and a function for updating that property.

import React, { useGlobal } from 'reactn';

const getRandomNumber = () => Math.floor(Math.random() * 100);

function MyComponent() {
  const [myNumber, setMyNumber] = useGlobal('myNumber');
  return <button onClick={() => setMyNumber(getRandomNumber())}>{myNumber}</button>;
}
withGlobal

Use withGlobal to return a higher-order component to convert global state values into props. This is highly analogous to react-redux's connect function.

The first parameter is a function for getting global state values.

The second parameter is a function for setting global state values (similar to dispatch).

import React, { withGlobal } from 'reactn';

// A button that displays the value and, when clicked, increments it.
function MyComponent(props) {
  return (
    <>
      My value is <button onClick={props.incrementValue} value={props.value} />
    </>
  );
}

export default withGlobal(
  // Set the `value` prop equal to the global state's `value` property.
  (global) => ({
    value: global.value,
  }),

  // Important Note: This is not the setGlobal helper function.
  // Set the `incrementValue` prop to a function that increments the global
  //   state's `value` property.
  (setGlobal) => ({
    incrementValue: () => {
      // Important Note: This is not the setGlobal helper function.
      // This is the parameter referenced 4 lines up.
      setGlobal((global) => ({
        value: global.value + 1,
      }));
    },
  })
)(MyComponent);
withInit

In some cases (such as when using Next.js), you may be unable to run a setup script prior to your ReactN components mounting. In order to instantiate your global state and reducers prior to mounting, you may use the withInit Higher Order Component. This HOC will await the setting of your global state before mounting the provided Lower Order Component (e.g. <App />).

import React, { useDispatch, useGlobal, withInit } from 'reactn';

const INITIAL_REDUCERS = {
  addOne: ({ count }) => ({
    count: count + 1,
  }),
};

const INITIAL_STATE = {
  count: 0,
};

export default withInit(
  INITIAL_STATE,
  INITIAL_REDUCERS
)(function App() {
  const addOne = useDispatch('addOne');
  const [count] = useGlobal('count');
  return <button onClick={addOne}>Count: {count}</button>;
});

Known issues

  • super(props) is incompatible with TypeScript. #126
  • Components re-render once per changed subscribed property. #129
  • Class components use componentWillUpdate without the UNSAFE_ prefix. #134
  • Class components are incompatible with Providers in newer versions of React. #132

Terminology

ReactN strictly maintains accurate terminology for its data structures. The majority of ReactN's data structures are meant to be black box to simplify the user experience, only referenced by name in the package's code. They are outlined here for transparency and to ease community contributions.

Dispatcher

When you pass a reducer to ReactN via addReducer, addReducers, useDispatch, or withInit, ReactN returns a dispatcher.

A dispatcher is a function that wraps a reducer, passing the global state and global reducers as parameters tying its return value to the global state. Dispatchers and reducers have a 1-to-1 relationship and are tightly bound to each other.

In documentation, dispatchers are often referred to as reducers to decrease the cognitive overhead and conceptually strengthen their 1-to-1 relationship.

For example, an "add" reducer may be defined as follows:

function add(global, _dispatch, n) {
  return { count: global.count + n };
}

When you call this reducer, you only need to call add(1). This difference in call signature is because you are calling the dispatcher.

A dispatcher, in pseudo-code, conceptually looks as follows:

function dispatchAdd(n) {
  const { dispatchers, set, state } = globalStateManager;
  const newGlobalState = add(state, dispatchers, n);
  return set(newGlobalState);
}

Global state manager

The global state manager is the core object that powers ReactN. It maintains the state, global dispatchers, and subscriptions.

Default global state manager

The default global state manager is the global state manager used by all of ReactN unless otherwise specified. To specify a different global state manager, you must use a Provider.

ReactN Components and Hooks will attempt to find a global state manager via the Context. If one does not exist via Context, it will fallback to the default global state manager.

Reducer

A reducer is a function that accepts the current global state, a map of all global reducers, and any number of additional parameters. A reducer returns a change to the global state. It does not need to return the entire new global state. It only needs to return key-value pairs of changed properties.

An example "add" reducer may be defined as follows:

function add(global, _dispatch, n) {
  return { count: global.count + n };
}

A reducer may be asynchronous (return a Promise) and asynchronously dispatch other reducers. You can use a reducer that dispatches other reducers to create a "saga" of state changes.

async function mySaga(global, dispatch, shouldMultiply) {
  if (global.count < 0) {
    await dispatch.add(1);
  }
  await dispatch.subtract(2);
  if (shouldMultiply) {
    await dispatch.multiply(3);
  }
}

mySaga(true); // shouldMultiply = true

Property reducer

A property reducer is a reducer that only changes one property. They only receive that property's value as a parameter instead of the entire global state object, and they do not receive the dispatch object as a parameter at all.

An example "add" property reducer may be defined as follows:

function add(count, n) {
  return count + n;
}

You must specify the property when using a property reducer. Property reducers cannot be added to or remembered by the global state manager.

import React, { useDispatch, useGlobal } from 'reactn';

function add(count, n) {
  return count + n;
}

function MyComponent() {
  const [count] = useGlobal('count');
  // Use the "add" property reducer on the "count" property.
  const dispatch = useDispatch(add, 'count');
  return <button onClick={() => dispatch(1)}>{count}</button>;
}

Sponsor

If you are a fan of this project, you may become a sponsor via GitHub's Sponsors Program.

Support

For support, reach out to us on the Reactiflux Discord channel #reactn.

chat

More Repositories

1

use-react-router

React Hook for pub-sub behavior using React Router.
TypeScript
567
star
2

fetch-suspense

A React hook compatible with React 16.6's Suspense component.
TypeScript
492
star
3

optimal-react-file-structure

Optimal file structure for React applications.
JavaScript
250
star
4

use-force-update

React Hook to force your function component to update
JavaScript
182
star
5

use-clippy

React Hook for reading from and writing to the user's clipboard.
TypeScript
179
star
6

use-mui

React hooks for Material UI
TypeScript
140
star
7

quicksort-js

An implementation of Quicksort in JavaScript/TypeScript.
TypeScript
61
star
8

lazy-i18n

Lazy load translations for your React application.
TypeScript
60
star
9

react-innertext

Returns the innerText of a React JSX object.
TypeScript
50
star
10

use-dimensions

A React hook for the React Native Dimensions API.
JavaScript
32
star
11

fetch-action-creator

Fetches using standardized, four-part asynchronous actions for redux-thunk.
JavaScript
28
star
12

quisi.do

https://quisi.do/
TypeScript
27
star
13

im-fine

A visual representation of depressive thoughts.
HTML
20
star
14

react-multi-context

Manage multiple React 16 contexts with a single component.
JavaScript
20
star
15

react-capsule

A React capsule is a global state instance that can be used across multiple React components.
TypeScript
16
star
16

use-async-function

A React hook for integrating asynchronous function state into React function component state.
TypeScript
15
star
17

use-awsui

React hooks for the AWS UI component library
TypeScript
14
star
18

react-datadog

A React wrapper for DataDog RUM
TypeScript
14
star
19

react-native-web-view

An implementation of React Native's WebView that allows for postMessage on iOS devices.
JavaScript
13
star
20

react-sparkline-svg

A React Component that renders a sparkline as an SVG.
TypeScript
12
star
21

reactn-devtools

ReactN DevTools allow you to view your ReactN state with the Redux DevTools browser extension
TypeScript
11
star
22

reactn-vs-redux

The same application, implemented and measured in both ReactN and redux.
JavaScript
11
star
23

node-package-template

A GitHub repository template for Node modules.
JavaScript
10
star
24

use-update-effect

useUpdateEffect is a React hook implementation of componentDidUpdate
TypeScript
10
star
25

rpg-overworld-engine

A tech demo for a browser-based, Pokemon-esque RPG overworld engine that even supports Internet Explorer 6.
JavaScript
10
star
26

sparkline-svg

Generate a Sparkline as an SVG.
TypeScript
10
star
27

peoplecott

Peoplecott attempts to unveil the immoral behavior funded by brand loyalty.
TypeScript
9
star
28

deep-proxy-polyfill

Recursively proxies an object.
TypeScript
9
star
29

react-segment-analytics

Segment integration with React
TypeScript
9
star
30

awsui-theme

Apply a custom theme to the AWS UI
TypeScript
7
star
31

textualsext

Textual Sext is a choose-your-own pornographic adventure game, designed by and featuring reddit user /u/textualsext. Click the images to scroll through the gallery, then choose an option for how to continue the storyline.
JavaScript
7
star
32

react-router-v6-sentry-browser-tracing-integration

Sentry browser tracing integration for React Router v6
TypeScript
6
star
33

use-awsui-router

Collection of React hooks for AWS UI with support for React Router.
TypeScript
6
star
34

react-pluralsight-score

A React component mimicking the Pluralsight Score IQ graph.
JavaScript
6
star
35

konami-js

Konami.js is an ES6 JavaScript instance that allows web developers to implement the Konami code on their web pages. By pressing up, up, down, down, left, right, left, right, B, A, Enter, one or more custom JavaScript functions will execute.
JavaScript
6
star
36

react-rainbow-text

Generates rainbow-colored text in React.
JavaScript
5
star
37

dota2huds

View a live demo of any Dota 2 HUD.
JavaScript
5
star
38

use-mouse-move

React hook for listening to mouse move events
TypeScript
4
star
39

medium-stats-api

An API endpoint for fetching Medium article stats.
JavaScript
4
star
40

mssql-query-builder

Dynamically build Microsoft SQL Server queries using JavaScript.
TypeScript
4
star
41

react-portfolio

A sleek portfolio design created in React.
TypeScript
4
star
42

rainbow-text

Rainbowify your text.
JavaScript
3
star
43

use-offline

React hook for listening to online/offline events.
TypeScript
3
star
44

with-router

A pub-sub alternative HOC to react-router's withRouter HOC.
JavaScript
3
star
45

super-mario-world-js

Super Mario World JS was a project for a college-level Programming Paradigms course.
JavaScript
3
star
46

spritesheet2gif-php

Converts sprite sheets to GIFs.
PHP
2
star
47

react-mui-tooltip

Create React tooltips similar to those used by Material-UI.
JavaScript
2
star
48

absolute-timestamp

Renders an absolute timestamp in React
TypeScript
2
star
49

use-awsui-table-item-description

Adds a description row to each table item.
TypeScript
2
star
50

hsl2rgb-js

Convert HSL to RGB.
JavaScript
2
star
51

breakout-of-smoking

The classic Breakout game themed as an anti-smoking campaign.
TypeScript
2
star
52

animal-crossing-music

Synchronize your day's background music with Animal Crossing.
TypeScript
2
star
53

use-ctrl-key

React hook for listening to when the Ctrl key is pressed
TypeScript
2
star
54

fullstory-react

FullStory integration with React
TypeScript
2
star
55

sonic-the-hedgehog-tribute

An artistic tribute to the Sonic the Hedgehog franchise.
JavaScript
2
star
56

meditative-breathing

A visual representation to guide meditative breathing.
CSS
2
star
57

awsui-dark-mode

Applies a dark mode theme to AWS UI components.
TypeScript
2
star
58

aws-console

automated AWS console
TypeScript
2
star
59

react-object-prop

Caches Object props in React so as to prevent unnecessary re-rendering.
JavaScript
2
star
60

configure-webpack

Easily generates a typical Webpack configuration.
JavaScript
1
star
61

docker-hub-webhook

A Docker container designed to listen for and redeploy images from Docker Hub webhooks.
JavaScript
1
star
62

sentry-react

A React wrapper to mount Sentry
TypeScript
1
star
63

use-page-transition

React hook for listening to page visibility events
TypeScript
1
star
64

glossary

Monorepo for Glossary application generation
TypeScript
1
star
65

use-key-down

React hook for listening to the keydown event.
TypeScript
1
star
66

password-generator

Generates a random string for password use.
HTML
1
star
67

shopping-list

A simple shopping list application.
JavaScript
1
star
68

delimiter

Places delimiters between items in an array.
JavaScript
1
star
69

reverse-proxy-nginx

The nginx layer of a containerized reverse proxy.
Dockerfile
1
star
70

quisido.com

A portfolio for Ace Quisido.
TypeScript
1
star
71

tf2-bingo

Mark your TF2 Bingo card as stereotypical situations unfold throughout your game!
HTML
1
star
72

use-params-memo

React's `useMemo` hook with a parameterized function
JavaScript
1
star
73

reverse-proxy-certbot

The certbot layer of a reverse proxy.
Dockerfile
1
star
74

rainbow-gradient

Generates a gradient of the colors of the rainbow.
JavaScript
1
star
75

platformer-engine

A 2D platformer engine implemented in the web browser.
JavaScript
1
star
76

react-quotes-carousel

A quotes carousel for React.
JavaScript
1
star
77

use-update-layout-effect

a useLayoutEffect hook that only triggers on update (not on mount)
TypeScript
1
star
78

spritesheet2gif-api

a back end API for converting sprite sheets to GIFs
PHP
1
star
79

trolley-solution-client

The Trolley Solution is a video board game based on the philosophical trolley problem.
TypeScript
1
star
80

react-native-meditative-breathing

A visual representation to guide meditative breathing.
JavaScript
1
star
81

table-sort

Open source JavaScript snippet that scans tabular data, appends arrow links to the header of sortable tables, and binary sorts the table by the data contained in that column when its sort link is clicked.
JavaScript
1
star
82

jquery-image-magnifier

an IE6-compliant image magnification tool
JavaScript
1
star
83

jquery-news-slider

A graphical news slider built in jQuery.
1
star
84

react-hooks

simple React hooks
1
star
85

docker-php-gd

A PHP/Apache Docker image configured to support the GD image library.
Dockerfile
1
star