LogRocket is a production Redux logging tool that lets you replay problems as if they happened in your own browser

Overview

Logger for Redux

npm npm Build Status

redux-logger

Now maintained by LogRocket!

LogRocket is a production Redux logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay Redux actions + state, network requests, console logs, and see a video of what the user saw.

For more informatiom about the future of redux-logger, check out the discussion here.

Table of contents

Install

npm i --save redux-logger

Typescript types are also available, via DefinitelyTyped:

npm i @types/redux-logger

Usage

import { applyMiddleware, createStore } from 'redux';

// Logger with default options
import logger from 'redux-logger'
const store = createStore(
  reducer,
  applyMiddleware(logger)
)

// Note passing middleware as the third argument requires redux@>=3.1.0

Or you can create your own logger with custom options:

import { applyMiddleware, createStore } from 'redux';
import { createLogger } from 'redux-logger'

const logger = createLogger({
  // ...options
});

const store = createStore(
  reducer,
  applyMiddleware(logger)
);

Note: logger must be the last middleware in chain, otherwise it will log thunk and promise, not actual actions (#20).

Options

{
  predicate, // if specified this function will be called before each action is processed with this middleware.
  collapsed, // takes a Boolean or optionally a Function that receives `getState` function for accessing current store state and `action` object as parameters. Returns `true` if the log group should be collapsed, `false` otherwise.
  duration = false: Boolean, // print the duration of each action?
  timestamp = true: Boolean, // print the timestamp with each action?

  level = 'log': 'log' | 'console' | 'warn' | 'error' | 'info', // console's level
  colors: ColorsObject, // colors for title, prev state, action and next state: https://github.com/LogRocket/redux-logger/blob/master/src/defaults.js#L12-L18
  titleFormatter, // Format the title used when logging actions.

  stateTransformer, // Transform state before print. Eg. convert Immutable object to plain JSON.
  actionTransformer, // Transform action before print. Eg. convert Immutable object to plain JSON.
  errorTransformer, // Transform error before print. Eg. convert Immutable object to plain JSON.

  logger = console: LoggerObject, // implementation of the `console` API.
  logErrors = true: Boolean, // should the logger catch, log, and re-throw errors?

  diff = false: Boolean, // (alpha) show diff between states?
  diffPredicate // (alpha) filter function for showing states diff, similar to `predicate`
}

Options description

level (String | Function | Object)

Level of console. warn, error, info or else.

It can be a function (action: Object) => level: String.

It can be an object with level string for: prevState, action, nextState, error

It can be an object with getter functions: prevState, action, nextState, error. Useful if you want to print message based on specific state or action. Set any of them to false if you want to hide it.

  • prevState(prevState: Object) => level: String
  • action(action: Object) => level: String
  • nextState(nextState: Object) => level: String
  • error(error: Any, prevState: Object) => level: String

Default: log

duration (Boolean)

Print duration of each action?

Default: false

timestamp (Boolean)

Print timestamp with each action?

Default: true

colors (Object)

Object with color getter functions: title, prevState, action, nextState, error. Useful if you want to paint message based on specific state or action. Set any of them to false if you want to show plain message without colors.

  • title(action: Object) => color: String
  • prevState(prevState: Object) => color: String
  • action(action: Object) => color: String
  • nextState(nextState: Object) => color: String
  • error(error: Any, prevState: Object) => color: String

logger (Object)

Implementation of the console API. Useful if you are using a custom, wrapped version of console.

Default: console

logErrors (Boolean)

Should the logger catch, log, and re-throw errors? This makes it clear which action triggered the error but makes "break on error" in dev tools harder to use, as it breaks on re-throw rather than the original throw location.

Default: true

collapsed = (getState: Function, action: Object, logEntry: Object) => Boolean

Takes a boolean or optionally a function that receives getState function for accessing current store state and action object as parameters. Returns true if the log group should be collapsed, false otherwise.

Default: false

predicate = (getState: Function, action: Object) => Boolean

If specified this function will be called before each action is processed with this middleware. Receives getState function for accessing current store state and action object as parameters. Returns true if action should be logged, false otherwise.

Default: null (always log)

stateTransformer = (state: Object) => state

Transform state before print. Eg. convert Immutable object to plain JSON.

Default: identity function

actionTransformer = (action: Object) => action

Transform action before print. Eg. convert Immutable object to plain JSON.

Default: identity function

errorTransformer = (error: Any) => error

Transform error before print.

Default: identity function

titleFormatter = (action: Object, time: String?, took: Number?) => title

Format the title used for each action.

Default: prints something like action @ ${time} ${action.type} (in ${took.toFixed(2)} ms)

diff (Boolean)

Show states diff.

Default: false

diffPredicate = (getState: Function, action: Object) => Boolean

Filter states diff for certain cases.

Default: undefined

Recipes

Log only in development

const middlewares = [];

if (process.env.NODE_ENV === `development`) {
  const { logger } = require(`redux-logger`);

  middlewares.push(logger);
}

const store = compose(applyMiddleware(...middlewares))(createStore)(reducer);

Log everything except actions with certain type

createLogger({
  predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN
});

Collapse actions with certain type

createLogger({
  collapsed: (getState, action) => action.type === FORM_CHANGE
});

Collapse actions that don't have errors

createLogger({
  collapsed: (getState, action, logEntry) => !logEntry.error
});

Transform Immutable (without combineReducers)

import { Iterable } from 'immutable';

const stateTransformer = (state) => {
  if (Iterable.isIterable(state)) return state.toJS();
  else return state;
};

const logger = createLogger({
  stateTransformer,
});

Transform Immutable (with combineReducers)

const logger = createLogger({
  stateTransformer: (state) => {
    let newState = {};

    for (var i of Object.keys(state)) {
      if (Immutable.Iterable.isIterable(state[i])) {
        newState[i] = state[i].toJS();
      } else {
        newState[i] = state[i];
      }
    };

    return newState;
  }
});

Log batched actions

Thanks to @smashercosmo

import { createLogger } from 'redux-logger';

const actionTransformer = action => {
  if (action.type === 'BATCHING_REDUCER.BATCH') {
    action.payload.type = action.payload.map(next => next.type).join(' => ');
    return action.payload;
  }

  return action;
};

const level = 'info';

const logger = {};

for (const method in console) {
  if (typeof console[method] === 'function') {
    logger[method] = console[method].bind(console);
  }
}

logger[level] = function levelFn(...args) {
  const lastArg = args.pop();

  if (Array.isArray(lastArg)) {
    return lastArg.forEach(item => {
      console[level].apply(console, [...args, item]);
    });
  }

  console[level].apply(console, arguments);
};

export default createLogger({
  level,
  actionTransformer,
  logger
});

To Do

  • Update eslint config to airbnb's
  • Clean up code, because it's very messy, to be honest
  • Write tests
  • Node.js support
  • React-native support

Feel free to create PR for any of those tasks!

Known issues

  • Performance issues in react-native (#32)

License

MIT

Comments
  • remove window

    remove window

    Assuming the existence of window means redux-logger cannot be used in universal applications.

    This removes the dependency on window being the global variable.

    opened by ganarajpr 18
  • Pinned all dependencies

    Pinned all dependencies

    :wave: Hello!

    We’re all trying to keep our software up to date, yet stable at the same time.

    This is the first in a series of automatic PRs to help you achieve this goal. It pins all of the dependencies in your package.json, so you have complete control over the exact state of your software.

    From now on you’ll receive PRs whenever one of your dependencies updates – in real time. This way you get all the benefits of up-to-date dependencies, while having them pinned at the same time. This means:

    • No more surprises because some of your dependencies didn’t follow SemVer. Your software is always in a state you know about, regardless of when someone does $ npm install.
    • If you have continuous integration set up for this repo, it’ll run automatically. Ideally, it will pass and you'll stay up to date with the press of a button. If the updated dependency does break your software, it won’t affect your users, because their dependencies are still pinned to the working state.
    • You can immediately identify which dependency updates break your software, because each one is tested in isolation. You’ll also have a branch ready to work on, so adapting to new APIs is way faster.

    Merge this PR and you’ll have up-to-date software without the headaches :sparkles:


    This pull request was created by greenkeeper.io. It keeps your software, up to date, all the time.

    Tired of seeing this sponsor message? Upgrade to the supporter plan! You'll also get your pull requests faster :zap:
    opened by evgenyrodionov 13
  • fix logger order

    fix logger order

    When redux dispatch an action, after calling the reducer, the listeners will be called. If the listener dispatch a new action, redux allow it, but the order of the log will in reverse. this PR fix the order in that case.

    opened by jetzhliu 12
  • Update build tools

    Update build tools

    Sorry if any of the changes are out of scope.

    CHANGELOG

    opened by thiamsantos 8
  • fix for mobile

    fix for mobile

    Looks like Mobile Safari / Chrome don't support String.prototype.repeat. I think this is an issue on iOS 8 and not iOS 9, but it'd be good just to make this more cross browser compatible.

    opened by matthewmueller 8
  • Logging of crashed actions

    Logging of crashed actions

    When an error is thrown during action execution (possibly meaning in listeners executed in reaction), the action should be logged to help with debugging.

    opened by hon2a 7
  • Add logger predicate

    Add logger predicate

    Implementation for https://github.com/fcomb/redux-logger/issues/4.

    const logger = createLogger({
      predicate: (getState, action) => action.type !== AUTH_REMOVE_TOKEN
    });
    const createStoreWithMiddleware = applyMiddleware(logger)(createStore);
    
    opened by vovacodes 7
  • Fixed webpack compatibility issue with ES6 exports

    Fixed webpack compatibility issue with ES6 exports

    Webpack has an issue interpreting ES6 exports from the root file. The end result causes createLogger to be wrapped in a an Object. By replacing the ES6 syntax with the default module system, as done in this PR, the issue is resolved

    example of problem:

    let createLogger = require('redux-logger');
    console.log(createLogger);
    /*
    Object {
    __esModule: true
    default: createLogger()
    __proto__: Object
    }
    */
    
    Examples of identical issues and resolutions:

    Quick glance of problem: https://github.com/algolia/instantsearch.js/pull/725 Deeper Explanation/Description of the issue: https://github.com/webpack/webpack/issues/706 Example of an identical fix: https://github.com/algolia/instantsearch.js/commit/81e7eee18bbd32014939f5ed61035d52a73f1ae6#diff-168726dbe96b3ce427e7fedce31bb0bc

    opened by qhenkart 6
  • Add module, jsnext:main to package.json

    Add module, jsnext:main to package.json

    Hey. I'm using your excellent logger in a package which I build using rollup. I grab the ES6 sources from various node_modules and then bundle everything together in a single JS file which I serve up.

    In order for rollup to do its thing properly, it needs an idea of where the ES6 sources live, which it gets from this value in your package.json file. So, if you'd like, here's that 2-line change to make it happen.

    Here's a bit of background on the pkg.module property.

    If you want to merge it back into the main project that would be nice, then I don't have to maintain my own fork. 😄 Thanks!

    opened by aviddiviner 5
  • Feature: Add log entry persistence hook

    Feature: Add log entry persistence hook

    The persister callback is both optional and mechanism-agnostic - i.e. may work with localStorage, REST endpoints, Firebase, etc - so long as it returns a Promise.

    The example has been updated to persist to localStorage, and the README updated to include recipes for REST and localStorage.

    Add optional constructor arg, persistencePredicate, that, if specified, this function will be called after each action is processed to determine if it should be persisted.

    opened by kareemf 5
  • fine grained level

    fine grained level

    fix #94 fix #54

    This PR would allow to have a fine grained control on the level of each part of the log (useful if you want the action to be an error to be able to see the stack trace for example).

    opened by mathieudutour 5
  • chore: move console messages to their own module

    chore: move console messages to their own module

    Summary

    The console.error messages are effectively constants that make reading the logic in index.js slightly more tedious.

    By moving these message strings to their own module, this slightly cleans up the logic in index.js.

    Also, this adds some tests for whether these console.errors were called with the appropriate text.

    Definitely understandable if this isn't merged as this type of code organization can be more a matter of taste than anything else.

    opened by jaebradley 0
  • Upgrade + Cleanup

    Upgrade + Cleanup

    1. Update dependencies to the latest version.
    2. Upgrade babel
    3. Upgrade eslint
    4. Upgrade Rollup
    5. Cleanup rollup config.
    6. Introduce Terser instead of Uglify
    7. Shrinkwrap to freeze dep.
    opened by vish1988 0
  • check the logger for trace and the options for withTrace

    check the logger for trace and the options for withTrace

    There was an issue with: https://github.com/evgenyrodionov/redux-logger/pull/205

    In the PR feedback it was recommended to make a withTrace option for the config, but instead it was used to check the logger object.

    What we want to happen is to have a withTrace option checked off the config as well as a trace property checked off of the logger object to make sure it supports trace.

    opened by danReynolds 3
  • Truncate colors if not supported

    Truncate colors if not supported

    This is a rehash of #203 but with different logic - 203 won't work any more due to some assumptions that the log methods were only called with max 2 parameters. This uses a lot of the same browser detection logic, with the addition of node - but has a totally different method.

    In short:

    • figure out browser support ahead of time. I've got node as not supporting colors (it does, but one would need to use ansi escape sequences which aren't really compatible with html color codes)

    • proxy each of the used console methods and pass arguments to truncateColorArguments -

    • if colors are supported, return arguments unchanged,

    • if colors aren't supported, look for any %c in string arguments and if found remove the number of %c found in the string from subsequent arguments - this removes the formatting information from the log.

    Also, fixed the CI build... it seems that someone left backticks in ./src/core.js and eslint was complaining.

    opened by tswaters 1
Releases(3.0.6)
  • 3.0.6(May 17, 2017)

    Changelog

    • fix: use Object.assign() instead of object spread operator because non-standard feature #229
    • fix: removed babel: {} options from package.json
    • fix: remove dangling comma because non-standard feature #230
    • fix: remove module and jsnext:main properties from package.json
    Source code(tar.gz)
    Source code(zip)
  • 3.0.2(May 17, 2017)

  • 3.0.1(Mar 30, 2017)

  • 3.0.0(Mar 23, 2017)

    Breaking change

    In 2.9.0 we introduced default logger, but this led to problems (#210).

    It was so bad that we publish 3 broken versions. So, we decided made a breaking change: by default we now export logger with default options and createLogger is now coming as named import.

    TL;DR

    You need to change your import

    import { applyMiddleware, createStore } from 'redux'
    
    - import createLogger from 'redux-logger'
    + import { createLogger } from 'redux-logger'
    // or
    - var createLogger = require('redux-logger')
    + var createLogger = require('redux-logger').createLogger
    
    const logger = createLogger()
    
    const store = createStore(
      reducer,
      applyMiddleware(logger)
    )
    

    or use logger with default settings

    import { applyMiddleware, createStore } from 'redux'
    import logger from 'redux-logger'
    // or const { logger } = require('redux-logger')
    
    const store = createStore(
      reducer,
      applyMiddleware(logger)
    )
    
    Source code(tar.gz)
    Source code(zip)
  • 2.10.2(Mar 21, 2017)

  • 2.10.0(Mar 21, 2017)

  • 2.9.0(Mar 21, 2017)

    It's more friendly for newcomers and now recommended way to use redux-logger.

    So, you can import default logger and use it with default options:

    import { logger } from 'redux-logger'
    
    const store = createStore(
      reducer,
      applyMiddleware(logger)
    )
    

    Changelog

    • expose default logger (import { logger } from 'redux-logger)
    • expose default settings (import { defaults } from 'redux-logger): useful if you use custom colors object and tired type default settings.

    Instead of

    import createLogger from 'redux-logger'
    
    const logger = createLogger({
      colors: {
        prevState: () => `#9E9E9E`,
        action: () => `#03A9F4`,
        nextState: () => `#4CAF50`,
        error: () => `#F20404`,
        title: ({ type }) => {
          if (type.indexOf(`started`) > -1) return `orange`;
          if (type.indexOf(`failed`) > -1) return `#F20404`;
          if (type.indexOf(`succeeded`) > -1) return `#4CAF50`;
          if (type.indexOf(`update`) > -1) return `#03A9F4`;
    
          return `inherit`;
        }
      }
    })
    

    you can

    import createLogger, { defaults } from 'redux-logger'
    
    const logger = createLogger({
      colors: {
        ...defaults.colors,
        title: ({ type }) => {
          if (type.indexOf(`started`) > -1) return `orange`;
          if (type.indexOf(`failed`) > -1) return `#F20404`;
          if (type.indexOf(`succeeded`) > -1) return `#4CAF50`;
          if (type.indexOf(`update`) > -1) return `#03A9F4`;
    
          return `inherit`;
        }
      }
    })
    
    Source code(tar.gz)
    Source code(zip)
  • 2.8.2(Mar 2, 2017)

  • 2.8.1(Feb 2, 2017)

    Remember this recipe?

    import createLogger from 'redux-logger';
    
    const logger = createLogger({
      actionTransformer: (action) => ({
        ...action,
        type: String(action.type),
      })
    });
    

    No more!

    Changelog

    • feat: implicitly convert action.type to String() in console.log (#195, #194, #106, #129, #128, #14, etc)
    Source code(tar.gz)
    Source code(zip)
  • 2.8.0(Feb 1, 2017)

  • 2.7.4(Oct 29, 2016)

    Changelog

    • fix: revert changes from #185 because redux-logger was broken in node.js

    Sorry for this, I was not careful and didn't tested that PR

    Source code(tar.gz)
    Source code(zip)
  • 2.7.2(Oct 28, 2016)

  • 2.7.1(Oct 28, 2016)

  • 2.7.0(Oct 5, 2016)

    Diff

    @sibelius merged redux-diff-logger and now you can use it by passing diff: true to options in createLogger(), f.e.

    const logger = createLogger({
      diff: true,
    });
    

    ❗️ Diff is very unstable and not tested, so we don't recommend use it as primary feature of logging.

    Formatter for title

    @spalger made titleFormatter option (#165)

    titleFormatter = (action: Object, time: String?, took: Number?) => title

    Format the title used for each action.

    Default: prints something like action @ ${time} ${action.type} (in ${took.toFixed(2)} ms)

    Bugfixes

    • fix: performance now checking for null and don't fail with TypeError (#173)
    • fix: default color of title now inherits console's default color (#176)
    Source code(tar.gz)
    Source code(zip)
  • 2.6.1(Feb 29, 2016)

  • 2.6.0(Feb 22, 2016)

    Fine-grained control over level 🚀

    Thankfully to @mathieudutour now we have very useful feature: fine-grained control over level.

    function

    const logger = createLogger({
      level: (action) => action.type === `SET_AUTH_TOKEN` ? `warning` : `log`
    });
    

    object

    const logger = createLogger({
      level: {
        prevState: `log`,
        action: `info`,
        nextState: `log`,
        error: `error`,
      },
    });
    

    object with functions

    const logger = createLogger({
      level: {
        prevState: false, // disable message of prevState
        action: ({ type }) => type.indexOf(`redux-form`) > -1 ? false : `info`, // don't show messages from redux-form (sorry, erikras, it's for demo only!)
        nextState: ({ type }) => type.indexOf(`user`) > -1 ? `warning` : `info`, // show nextState as warning if action is user-related
        error: `error`,
      },
    });
    
    Source code(tar.gz)
    Source code(zip)
  • 2.5.2(Feb 11, 2016)

  • 2.5.1(Feb 11, 2016)

  • 2.5.0(Feb 3, 2016)

    redux-logger now supports server-side rendering without pain :tada:

    Chanelog

    • fixed: replaced window.console for console as default value for logger option (#121)
    Source code(tar.gz)
    Source code(zip)
  • 2.4.0(Jan 22, 2016)

    Changelog

    • fix: log order was messed when store dispatched new action in response of previous (thanks, @jetzhliu, #102)
    • fix: next state wasn't logged when spawned error (thanks, @cappslock, #115)
    Source code(tar.gz)
    Source code(zip)
  • 2.3.1(Dec 17, 2015)

  • 2.3.0(Dec 16, 2015)

  • 2.2.1(Dec 10, 2015)

    Changelog

    • feature: colors.title with action argument for better color management

    Thankfully to @af and #100 now you can paint even title! 💅 For example, you can paint title for red if action has fail in type.

    const logger = createLogger({
      colors: {
        title: (action) => {
          if (action.type.indexOf(`fail`)) {
            return `red`;
          } else {
            return `#111`;
          }
        };
      }
    })
    
    Source code(tar.gz)
    Source code(zip)
  • 2.1.4(Dec 8, 2015)

  • 2.1.3(Dec 7, 2015)

  • 2.1.2(Dec 7, 2015)

  • 2.1.1(Dec 6, 2015)

    Changelog

    • deprecated: transformer is deprecated, use stateTransformer instead
    • feature: colors object

    Colors

    We have so much requests (#91, #94 and other) about control over messages, so we bring it to life 🎉 Logger now have colors: Object option with 3 keys: prevState, action, nextState, each must return color as string (for example, red or #03A9F4).

    • prevState(prevState: Object) => color: String
    • action(action: Object) => color: String
    • nextState(nextState: Object) => color: String

    colors also can be false if you don't need paint message or your env doesn't support console formatting (#92).

    Examples

    Disable colors

    const logger = createLogger({
      colors: false
    });
    

    Paint action message with type AUTH_TOKEN_REMOVE to red

    const logger = createLogger({
      colors: {
        prevState: () => `#9E9E9E`,
        action: (action) => action.type === `AUTH_REMOVE_TOKEN` && `red`,
        nextState: () => `#4CAF50`,
      }
    });
    
    Source code(tar.gz)
    Source code(zip)
  • v2.0.4(Oct 15, 2015)

  • v2.0.3(Oct 6, 2015)

  • v2.0.2(Oct 5, 2015)

Owner
Record and replay user sessions to fix bugs faster.
null
HTML to React parser that works on both the server (Node.js) and the client (browser):

HTML to React parser that works on both the server (Node.js) and the client (browser):

Mark 1.5k Jan 6, 2023
A simple way of loading inline es-modules on modern browser

ES inline module A simple way of loading inline es-modules on modern browser. Usage Use inlineImport to dynamically import inline scripts. <script typ

稀土 40 Dec 22, 2022
React adblocker detect - Provides you with react hook to detect is an adblocker is enabled

React adblocker detect - Provides you with react hook to detect is an adblocker is enabled

Shubham Singh Chahar 3 Mar 15, 2022
Helps you to track the size and position of html-elements in solid-js

solid-boundaries Helps you to track the size and position of html-elements in solid-js. What does it do? See it in action here, or see it on CodeSandb

Erik Verweij 15 Jan 1, 2023
This project allows you leverage Million's Virtual DOM while writing React code

This project allows you leverage Million's Virtual DOM while writing React code. Get faster rendering (a compiler optimizes virtual DOM beforehand) while ensuring the same developer experience React provides.

Aiden Bai 白宇彤 370 Dec 28, 2022
Using eventChannel in React Redux-Saga, API in below link.

Using eventChannel in React Redux-Saga, API in below link.

James Johnson 15 Oct 1, 2022
@custom-elements-manifest/analyzer plugin to ✨ automatically ✨ create react wrappers for your custom elements

cem-plugin-reactify @custom-elements-manifest/analyzer plugin to automatically create React wrappers for your custom elements based on your custom ele

Pascal Schilp 9 Jul 29, 2022
React-Native library for the WidgetKit framework. Integrate a Widget into your App 🍏📱

react-native-widgetkit React-Native Library for the iOS ?? WidgetKit framework Table of Contents ?? Introduction ??‍?? Installation ??‍ Usage ????‍??

Fasky 120 Dec 21, 2022
Because your state management code should be domain-agnostic.

Because your state management code should be domain-agnostic.

Zachary DeRose 12 Nov 19, 2022
React code splitting made easy. Reduce your bundle size without stress ✂️ ✨ .

React code splitting made easy. Reduce your bundle size without stress ✂️ ✨ . npm install @loadable/component Docs See the documentation at loadable-c

Greg Bergé 7k Jan 3, 2023
🌈 Easy-to-use media queries for your React project

?? React Super Simple Media Queries Easy-to-use media queries for your React project Features ⚡️ Fast & Light with MatchMedia API ⚡️ ?? Auto detects t

Igor Talpa 4 Sep 14, 2022
A Cool VSCode extension that lets you create react component files/folders instantly with boilerplate code. It also handles imports/exports on its own.

React Component Generator v1.0.0 A cool VSCode extension that lets you create your component's files/folders instantly with boilerplate code. Also aut

Udit Kumar 8 Dec 7, 2022
A simple React app that lets you play Hangman in your browser

Hacktoberfest 2021 with IEEE-VIT ❤️ Hangman-React is a simple Hangman Game built using React JS. Support open source software by participating in Hack

IEEE VIT Student Chapter 14 May 18, 2022
Tabbed navigation that you can swipe between, each tab can have its own ScrollView and maintain its own scroll position between swipes. Pleasantly animated. Customizable tab bar

react-native-scrollable-tab-view This is probably my favorite navigation pattern on Android, I wish it were more common on iOS! This is a very simple

Tomas Roos 6.8k Dec 31, 2022
Chess Analysis is a free tool that allows you to get reports from your own matches.

Chess Analysis ♟️ Chess Analysis is a free tool that allows you to get reports from your own matches. Import your PGN and check it now. Screen.Recordi

Paulo Viana 1 Nov 15, 2022
Snoopy is a profiling tool for React Native, that lets you snoop on the React Native Bridge.

React Native Snoopy UPDATE: I wrote an article with the story behind this library. Snoopy is a profiling tool for React Native, that lets you snoop on

Dotan J. Nahum 527 Sep 29, 2022
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

Redux 13.3k Jan 2, 2023
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

Redux 13.3k Jan 1, 2023
DevTools for Redux with hot reloading, action replay, and customizable UI

Redux DevTools Developer Tools to power-up Redux development workflow or any other architecture which handles the state change (see integrations). It

Redux 13.3k Jan 3, 2023
A high-performance timer based profiler for React Native that helps you track big performance problems.

Slowlog A high-performance timer for React Native that helps you track big performance problems. Use it as a first line of defense, before tools like

Dotan J. Nahum 371 Nov 21, 2022