Skip to main content

Application State

Jupyter React uses Zustand for state management. This provides a lightweight, performant way to manage global state and enables bi-directional communication between your React application and JupyterLab/Lumino internals.

Architecture Overview

Main Store: JupyterReactStore

The central store that manages the Jupyter connection and global state.

Accessing the Store

import { useJupyterReactStore } from '@datalayer/jupyter-react';

function MyComponent() {
// Get entire store
const store = useJupyterReactStore();

// Or select specific values (recommended for performance)
const kernel = useJupyterReactStore(state => state.kernel);
const serviceManager = useJupyterReactStore(state => state.serviceManager);
const colormode = useJupyterReactStore(state => state.colormode);

return <div>Kernel loaded: {kernel ? 'Yes' : 'No'}</div>;
}

Store Properties

PropertyTypeDescription
kernelKernel | undefinedThe active Jupyter kernel
kernelIsLoadingbooleanWhether a kernel is being initialized
serviceManagerServiceManager | undefinedJupyterLab service manager for API access
jupyterConfigIJupyterConfigCurrent Jupyter configuration
colormode'light' | 'dark'Current color mode
versionstringLibrary version
jupyterLabAdapterJupyterLabAppAdapterAdapter for JupyterLab app integration

Store Actions

ActionDescription
setColormode(colormode)Change the color mode
setServiceManager(manager)Set the service manager
setJupyterConfig(config)Update Jupyter configuration
setJupyterLabAdapter(adapter)Set the JupyterLab adapter

Component-Specific Stores

Each major component has its own store for managing component-specific state.

NotebookStore

Manages state for notebook instances.

import { useNotebookStore } from '@datalayer/jupyter-react';

function NotebookController({ notebookId }: { notebookId: string }) {
const notebookStore = useNotebookStore();

// Get notebook adapter
const adapter = notebookStore.selectNotebookAdapter(notebookId);

// Execute operations
const runAll = () => notebookStore.runAll(notebookId);
const insertCell = () =>
notebookStore.insertCell(notebookId, 'code', 0, 'print("Hello")');
const deleteCell = () => notebookStore.deleteCell(notebookId, 0);

// Read notebook state
const cells = notebookStore.readAllCells(notebookId, 'brief');
const kernelStatus = notebookStore.selectKernelStatus(notebookId);

return (
<div>
<button onClick={runAll}>Run All</button>
<button onClick={insertCell}>Insert Cell</button>
<span>Kernel: {kernelStatus}</span>
</div>
);
}

Notebook Store Actions

ActionParametersDescription
run(id)notebook IDRun the active cell
runAll(id)notebook IDRun all cells
insertCell(id, type, index, source)notebook ID, cell type, position, sourceInsert a new cell
deleteCell(id, index)notebook ID, cell indexDelete a cell
updateCell(id, index, source)notebook ID, cell index, new sourceUpdate cell content
readCell(id, index)notebook ID, cell indexRead cell content and outputs
readAllCells(id, format)notebook ID, 'brief' or 'detailed'Read all cells
clearAllOutputs(id)notebook IDClear all cell outputs
interrupt(id)notebook IDInterrupt kernel execution
undo(id)notebook IDUndo last action
redo(id)notebook IDRedo last undone action
changeCellType(id, type)notebook ID, cell typeChange active cell type
save(mutation)save mutationSave notebook

CellStore

Manages state for individual cell components.

import { useCellsStore } from '@datalayer/jupyter-react';

function CellController({ cellId }: { cellId: string }) {
const cellStore = useCellsStore();

// Get cell state
const source = cellStore.getSource(cellId);
const outputsCount = cellStore.getOutputsCount(cellId);
const isExecuting = cellStore.isAnyCellExecuting;

// Execute cell
const execute = () => cellStore.execute(cellId);

// Update source
const updateSource = (newSource: string) => {
cellStore.setSource(cellId, newSource);
};

return (
<div>
<button onClick={execute} disabled={isExecuting}>
{isExecuting ? 'Running...' : 'Run'}
</button>
<span>Outputs: {outputsCount}</span>
</div>
);
}

Cell Store Properties & Actions

Property/ActionDescription
getSource(id)Get cell source code
setSource(id, source)Update cell source
getOutputsCount(id)Get number of outputs
getAdapter(id)Get cell adapter
execute(id)Execute cell
isKernelSessionAvailable(id)Check if kernel is ready
areAllKernelSessionsReadyCheck if all cells have kernel access
isAnyCellExecutingCheck if any cell is running

OutputStore

Manages output state for Output components.

import { useOutputsStore } from '@datalayer/jupyter-react';

function OutputController({ outputId }: { outputId: string }) {
const outputStore = useOutputsStore();

// Get output state
const adapter = outputStore.getAdapter(outputId);
const model = outputStore.getModel(outputId);

// Execute code
const executeCode = (code: string) => {
adapter?.execute(code);
};

return <button onClick={() => executeCode('print("Hello")')}>Execute</button>;
}

TerminalStore

Manages terminal instance state.

import { useTerminalStore } from '@datalayer/jupyter-react';

function TerminalController() {
const terminalStore = useTerminalStore();

// Access terminal state and adapters
const terminals = terminalStore.terminals;

return <div>Active terminals: {terminals.size}</div>;
}

ConsoleStore

Manages console (REPL) instance state.

import { useConsoleStore } from '@datalayer/jupyter-react';

function ConsoleController() {
const consoleStore = useConsoleStore();

// Access console state
const consoles = consoleStore.consoles;

return <div>Active consoles: {consoles.size}</div>;
}

Using with Props: useJupyterReactStoreFromProps

For components that need to initialize Jupyter from props:

import { useJupyterReactStoreFromProps } from '@datalayer/jupyter-react';

function MyJupyterApp() {
const store = useJupyterReactStoreFromProps({
jupyterServerUrl: 'http://localhost:8888',
jupyterServerToken: 'my-token',
startDefaultKernel: true,
defaultKernelName: 'python3',
lite: false,
});

if (store.kernelIsLoading) {
return <div>Loading kernel...</div>;
}

return <div>Kernel ready: {store.kernel?.connection?.status}</div>;
}

Direct Store Access (Vanilla)

For non-React code or advanced use cases, access stores directly:

import {
jupyterReactStore,
notebookStore,
cellsStore,
} from '@datalayer/jupyter-react';

// Get current state
const state = jupyterReactStore.getState();
console.log('Current kernel:', state.kernel);

// Subscribe to changes
const unsubscribe = jupyterReactStore.subscribe(state => {
console.log('Kernel changed:', state.kernel);
});

// Execute notebook actions directly
notebookStore.getState().runAll('my-notebook-id');

Source Code

The state management implementation can be found in the source code.