Jotai DevTools

repository·main·Indexed 41 days ago

https://github.com/jotaijs/jotai-devtools

A visual debugging toolkit for Jotai applications featuring atom value inspection, time-travel debugging, and support for async atoms. Version 0.15.0-alpha.0 requires Jotai >=v3.0.0 and React >=18.0.0. It provides a DevTools UI component, programmatic hooks like useAtomsSnapshot and useAtomDevtools, and integration with Redux DevTools via createReduxConnection.

Tokens
5.2K
Snippets
20
Records
25
Agent score
52%

What's inside Jotai DevTools

  1. Tree-shake DevTools for Production

    main

    Since jotai-devtools is intended for development, you should prevent it from being included in your production bundle.

    Vite

    Use process.env.NODE_ENV to conditionally render the component and import the CSS inline using the ?inline suffix.

    Next.js

    Use next/dynamic with ssr: false to load the DevTools component only when process.env.NODE_ENV !== 'production'.

    // Vite Example
    import { DevTools } from 'jotai-devtools';
    import css from 'jotai-devtools/styles.css?inline';
    
    const JotaiDevTools = () =>
      process.env.NODE_ENV !== 'production' ? (
        <>
          <style>{css}</style>
          <DevTools />
        </>
      ) : null;
  2. Migrate from jotai/react/devtools to jotai-devtools

    main

    If you are upgrading from the old jotai/react/devtools package, update your imports to use the new jotai-devtools package.

    Old Import:

    import { ... } from 'jotai/react/devtools';

    New Import:

    import { ... } from 'jotai-devtools';
  3. Use the UI DevTools component

    main

    The DevTools component provides a visual interface for debugging atom values and performing time-travel debugging. You can use it in two modes:

    Provider-less mode

    If you are not using a custom Jotai store, simply include the component and its CSS in your application.

    With a custom Provider

    If you are using a custom store via a Provider, pass that same store to the DevTools component to ensure they are synchronized.

    Note: You must import jotai-devtools/styles.css for the UI to render correctly.

    // Provider-less
    import { DevTools } from 'jotai-devtools';
    import 'jotai-devtools/styles.css';
    
    const App = () => (
      <>
        <DevTools />
        {/* your app */}
      </>
    );
    
    // With Provider
    import { createStore, Provider } from 'jotai';
    import { DevTools } from 'jotai-devtools';
    import 'jotai-devtools/styles.css';
    
    const customStore = createStore();
    
    const App = () => (
      <Provider store={customStore}>
        <DevTools store={customStore} />
        {/* your app */}
      </Provider>
    );
  4. Install jotai-devtools

    main

    Install the jotai-devtools package using your preferred package manager to enable debugging and time-travel features for Jotai atoms.

    Prerequisites:

    • Jotai version >=v3.0.0
    • React version >=18.0.0
    # yarn
    yarn add jotai-devtools
    
    # npm
    npm install jotai-devtools --save
  5. Configure Next.js for Jotai DevTools

    main

    When using Next.js, you must enable transpilePackages in your next.config.ts (or .js) to ensure the DevTools CSS and components are transpiled correctly.

    // next.config.ts
    const nextConfig = {
      transpilePackages: ['jotai-devtools'],
    };
    
    module.exports = nextConfig;
  6. Understand the DevStore interface

    main

    The DevStore type defines the extended capabilities added to a Jotai store when using DevTools. It provides methods to inspect the internal state of atoms and manage atom mounting/restoration. This interface is used by the DevTools to bridge the gap between the Jotai store and the UI debugger.

    Key methods include:

    • get_internal_weak_map(): Returns a getter to access the internal state of a specific atom.
    • get_mounted_atoms(): Returns a Set of atoms currently mounted in the store.
    • get_mounted_map(): Provides access to the mounted map.
    • restore_atoms(values): Accepts an iterable of [Atom, value] tuples to restore atom states.
    export type DevStore = {
      get_internal_weak_map: () => {
        get: (atom: Atom<unknown>) => INTERNAL_AtomState | undefined;
      };
      get_mounted_atoms: () => Set<Atom<unknown>>;
      get_mounted_map: () => Pick<INTERNAL_MountedMap, 'get'>;
      restore_atoms: (values: Iterable<readonly [Atom<unknown>, unknown]>) => void;
    };
  7. Use AtomsSnapshot for state inspection

    main

    The AtomsSnapshot type represents a read-only point-in-time view of the atom state within the store. It is used to capture the current values and dependency graph of atoms.

    It consists of:

    • values: An immutable Map where keys are atoms and values are their current state (AnyAtomValue).
    • dependents: An immutable Map where keys are atoms and values are Sets of atoms that depend on them.
    export type AtomsSnapshot = Readonly<{
      values: AtomsValues;
      dependents: AtomsDependents;
    }>;
  8. Migrate from @emotion/react to native CSS

    main

    Recent versions of jotai-devtools have replaced @emotion/react with native CSS. To migrate:

    1. Remove @emotion/react from your dependencies:
      yarn remove @emotion/react
      # or
      npm uninstall @emotion/react
    2. Import the new CSS file in your entry point:
      import 'jotai-devtools/styles.css';
  9. Configure DevToolsProps

    main

    The DevTools component accepts several props to customize its behavior, appearance, and performance.

    PropTypeDefaultDescription
    isInitialOpenbooleanfalseWhether the DevTools panel is open by default.
    storeStore-Pass a custom Jotai store.
    theme'dark' | 'light''light'The visual theme of the DevTools.
    position'top-right' | 'top-left' | 'bottom-right' | 'bottom-left'The screen position of the DevTools UI.
    noncestring-Custom nonce for CSP to allow inline styles.
    optionsobject-Configuration object for internal behaviors.

    options properties:

    • shouldShowPrivateAtoms (boolean, default: false): If true, shows atoms used internally by utilities like atomWithStorage.
    • shouldExpandJsonTreeViewInitially (boolean, default: false): Expands JSON tree views on initial render.
    • timeTravelPlaybackInterval (number, default: 750): Interval in ms between time-travel steps.
    • snapshotHistoryLimit (number, default: Infinity): Max snapshots to keep. Recommended value is ~30 to manage memory.
    type DevToolsProps = {
      isInitialOpen?: boolean;
      store?: Store;
      theme?: 'dark' | 'light';
      position?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
      nonce?: string;
      options?: {
        shouldShowPrivateAtoms?: boolean;
        shouldExpandJsonTreeViewInitially?: boolean;
        timeTravelPlaybackInterval?: number;
        snapshotHistoryLimit?: number;
      };
    };
  10. Use Jotai DevTools hooks

    main

    The package exports several hooks for programmatic access to atom state and Redux DevTools integration:

    • useAtomsSnapshot: Access the current snapshot of atoms.
    • useGotoAtomsSnapshot: Navigate to a specific atom snapshot.
    • useAtomsDebugValue: Get debug values for atoms.
    • useAtomDevtools: Redux DevTools integration hook.
    • useAtomsDevtools: Redux DevTools integration hook.
    import {
      useAtomsSnapshot,
      useGotoAtomsSnapshot,
      useAtomsDebugValue,
      useAtomDevtools,
      useAtomsDevtools,
    } from 'jotai-devtools';
  11. Navigate time travel with useTimeTravelNavigateActions

    main

    The useTimeTravelNavigateActions hook provides manual controls for navigating through the snapshot history (stepping forward, backward, or resetting to the start).

    import { useTimeTravelNavigateActions } from 'jotai-devtools';
    
    const { prev, next, reset } = useTimeTravelNavigateActions();
    
    // Usage in UI:
    // <button onClick={prev.onClick} disabled={!prev.isPossible}>Prev</button>
    // <button onClick={next.onClick} disabled={!next.isPossible}>Next</button>
    // <button onClick={reset}>Reset</button>