{"id":7443,"library":"nbdime","title":"nbdime (Jupyter Notebook Diff & Merge)","description":"nbdime provides tools for diffing and merging Jupyter Notebooks. It offers both a command-line interface for integration with version control systems (like Git) and a visual, interactive web interface for richer diffs and merges. The library is currently at version 4.0.4 and is actively maintained by the Project Jupyter team, with releases often coinciding with major JupyterLab updates.","status":"active","version":"4.0.4","language":"en","source_language":"en","source_url":"https://github.com/jupyter/nbdime","tags":["jupyter","notebook","diff","merge","git","version control","data science"],"install":[{"cmd":"pip install nbdime","lang":"bash","label":"Install core library and server extension"},{"cmd":"jupyter nbextension install --py nbdime --sys-prefix --symlink","lang":"bash","label":"Enable for classic Jupyter Notebook (optional)"},{"cmd":"jupyter labextension install @jupyterlab/nbdime-extension@3","lang":"bash","label":"Enable for JupyterLab 3 (for nbdime < 4.0.0, or if auto-install fails)"}],"dependencies":[{"reason":"Core dependency for notebook structure parsing.","package":"nbformat"},{"reason":"For integration with classic Jupyter Notebook and server functionalities.","package":"notebook"},{"reason":"Underpins the JupyterLab/Notebook server and extension architecture.","package":"jupyter_server"}],"imports":[{"symbol":"diff_notebooks","correct":"from nbdime.diff_files import diff_notebooks"},{"symbol":"merge_notebooks","correct":"from nbdime.merge_files import merge_notebooks"},{"note":"The primary entry points are typically command-line or specific programmatic functions; the top-level 'nbdime' module itself is not usually imported for direct functionality.","wrong":"import nbdime","symbol":"main","correct":"from nbdime.webapp import main"}],"quickstart":{"code":"import nbformat\nfrom pathlib import Path\nimport subprocess\n\n# Create two dummy notebooks for demonstration\nnb1 = nbformat.v4.new_notebook()\nnb1.cells.append(nbformat.v4.new_code_cell(\"print('Hello from A')\"))\nnb1_path = Path(\"notebook_a.ipynb\")\nwith open(nb1_path, \"w\", encoding=\"utf-8\") as f:\n    nbformat.write(nb1, f)\n\nnb2 = nbformat.v4.new_notebook()\nnb2.cells.append(nbformat.v4.new_code_cell(\"print('Hello from B')\"))\nnb2.cells.append(nbformat.v4.new_markdown_cell(\"## A new section\\nThis is a new section in notebook B.\"))\nnb2_path = Path(\"notebook_b.ipynb\")\nwith open(nb2_path, \"w\", encoding=\"utf-8\") as f:\n    nbformat.write(nb2, f)\n\nprint(f\"Created {nb1_path} and {nb2_path}\")\n\n# Run nbdime diff from the command line\nprint(\"\\n--- Running nbdime diff in terminal mode ---\")\ntry:\n    # Use --diff-alg=terminal to get output directly in the console\n    result = subprocess.run(\n        [\"nbdime\", \"diff\", str(nb1_path), str(nb2_path), \"--diff-alg=terminal\"],\n        capture_output=True, text=True, check=True\n    )\n    print(result.stdout)\nexcept subprocess.CalledProcessError as e:\n    print(f\"Error running nbdime diff: {e.stderr}\")\n\n# To open in a browser (default behavior if --diff-alg is not specified)\n# print(\"\\n--- Running nbdime diff in browser (opens new tab) ---\")\n# subprocess.Popen([\"nbdime\", \"diff\", str(nb1_path), str(nb2_path)])\n# print(\"Check your browser for the visual diff. Press Ctrl+C to stop this script after viewing.\")\n# import time; time.sleep(10) # Give time to view, then uncomment cleanup\n\n# Clean up\nnb1_path.unlink()\nnb2_path.unlink()\nprint(f\"\\nCleaned up {nb1_path} and {nb2_path}\")","lang":"python","description":"This quickstart demonstrates how to create two simple Jupyter notebooks and then use the `nbdime` command-line tool to perform a diff between them, showing the output directly in the terminal. The default `nbdime diff` command would open a browser for a richer visual diff."},"warnings":[{"fix":"Upgrade your Python environment to 3.6 or a newer version (e.g., 3.9, 3.10, 3.11).","message":"nbdime 3.x and newer require Python 3.6+ for installation and execution. Older Python environments (e.g., Python 2.7, Python 3.5) are no longer supported and will lead to installation failures or runtime errors.","severity":"breaking","affected_versions":"<3.x"},{"fix":"For JupyterLab 4, `pip install nbdime` should be sufficient. For JupyterLab 3, ensure you run `jupyter labextension install @jupyterlab/nbdime-extension` (or `@jupyterlab/nbdime-extension@3`) after `pip install nbdime`.","message":"With `nbdime` version 4.0.0 and above, the JupyterLab frontend extension installation process changed. For JupyterLab 4, `pip install nbdime` should automatically handle the frontend extension. However, for JupyterLab 3 and below, you still need to explicitly run `jupyter labextension install @jupyterlab/nbdime-extension` (and possibly specify a compatible version like `@3`) after installing the Python package.","severity":"breaking","affected_versions":">=4.0.0 (JupyterLab 4 vs. 3)"},{"fix":"To get terminal output, use `nbdime diff --diff-alg=terminal file1.ipynb file2.ipynb`. To prevent browser launch, use `--browser=none`.","message":"By default, `nbdime diff` and `nbdime merge` commands launch a web browser to display the visual diff/merge interface. Users expecting immediate terminal output may be surprised. For command-line diff output, use the `--diff-alg=terminal` flag.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure all other packages in your environment are up-to-date. If issues persist, consider isolating `nbdime` in a virtual environment.","message":"The `ipython_genutils` dependency was removed in `nbdime` version 3.2.0. While this is an improvement, environments with other packages that still explicitly rely on or bundle `ipython_genutils` might experience minor dependency conflicts or warnings during upgrades.","severity":"deprecated","affected_versions":">=3.2.0"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Ensure `nbdime` is installed (`pip install nbdime`) and that your Python environment's script directory (where executables are placed) is included in your system's PATH. Restart your terminal after installation.","cause":"The `nbdime` executable is not in your system's PATH, or the `nbdime` Python package was not installed correctly.","error":"nbdime: command not found"},{"fix":"Import specific functions from submodules, for example: `from nbdime.diff_files import diff_notebooks` or `from nbdime.merge_files import merge_notebooks`.","cause":"You are attempting an incorrect programmatic import. There is no top-level `nbdime.nbdime` submodule directly.","error":"No module named 'nbdime.nbdime'"},{"fix":"For `nbdime>=4.0.0` and JupyterLab 4, `pip install nbdime` should automatically handle the frontend. For JupyterLab 3, explicitly install a compatible extension version, e.g., `jupyter labextension install @jupyterlab/nbdime-extension@3`. Always consult the official `nbdime` documentation for the latest compatibility matrix.","cause":"There is a version mismatch between your installed JupyterLab and the `@jupyterlab/nbdime-extension` you are trying to install. This is common when upgrading JupyterLab or nbdime independently.","error":"jupyter labextension install @jupyterlab/nbdime-extension failed with a compatibility error or 'Package not found'"},{"fix":"Upgrade your `notebook` and `jupyter_server` packages to their latest compatible versions. Then, reinstall `nbdime`. For example: `pip install --upgrade notebook jupyter_server nbdime`.","cause":"This error can occur due to conflicts with `nbdime`'s monkey-patching of Jupyter server components and outdated `notebook` or `jupyter_server` dependencies.","error":"TraitError: The 'log' trait of a ServerApp instance must be a Logger, but a value of <nbdime.notebook_patch.PatchLogger object at 0x...> was specified."}]}