jupyter/notebook
Jupyter Interactive Notebook
Bundles JupyterLab components into Jupyter Notebook v7's web interface
The system starts with rspack scanning package.json files to discover extensions, then uses module federation to bundle them into a single application. During runtime, the NotebookApp instance loads and activates plugins, which register services and UI components. When users interact with the interface, routing logic determines how to handle different document types - notebooks open in the notebook interface while other files open in appropriate editors. Extensions communicate through JupyterLab's plugin system using dependency injection.
Under the hood, the system uses 2 feedback loops, 3 data pools, 3 control points to manage its runtime behavior.
A 8-component fullstack. 85 files analyzed. Data flows through 5 distinct pipeline stages.
How Data Flows Through the System
The system starts with rspack scanning package.json files to discover extensions, then uses module federation to bundle them into a single application. During runtime, the NotebookApp instance loads and activates plugins, which register services and UI components. When users interact with the interface, routing logic determines how to handle different document types - notebooks open in the notebook interface while other files open in appropriate editors. Extensions communicate through JupyterLab's plugin system using dependency injection.
- Package discovery and bundling — rspack.config.js scans the workspace to find all packages with JupyterLab extensions, reads their plugin definitions from package.json metadata, and uses module federation to create a single bundle with dynamic imports [PackageData → Application bundle] (config: LabApp.expose_app_in_browser)
- Application initialization — NotebookApp constructor creates the main application instance, sets up the custom NotebookShell, registers base model factories, and loads MIME renderer extensions [NotebookApp.IOptions → Application instance] (config: JupyterNotebookApp.expose_app_in_browser)
- Plugin registration and activation — The application discovers all JupyterFrontEndPlugin instances from the bundled extensions, resolves their dependencies, and activates them in dependency order [JupyterFrontEndPlugin → Active services]
- Document routing and opening — When users click on files or URLs, the IDocumentWidgetOpener service examines the file extension and factory preferences - .ipynb files route to the notebook interface while other files open in text editors or appropriate viewers [File paths and factory options → Document opening actions]
- Interface rendering and interaction — The NotebookShell manages widget placement and layout while individual extensions provide specific functionality like search, help menus, console access, and kernel status indicators [Widget instances → User interface]
Data Models
The data structures that flow between stages — the contracts that hold the system together.
@jupyterlab/applicationTypeScript interface with id: string, activate: function, requires?: token[], optional?: token[], provides?: token, autoStart?: boolean, description?: string
Extensions define plugins that get registered with the application during startup and activated when their dependencies are available
buildutils/src/utils.tsTypeScript type with name: string, private?: boolean, version?: string, plus arbitrary package.json fields
Created by reading package.json files, used to manage dependencies and workspace operations
buildutils/src/utils.tsTypeScript type with data: PackageData, name: string, packageJsonPath: string, packagePath: string, private: boolean
Generated during workspace analysis, used throughout build and development tools to represent each package in the monorepo
packages/application/src/app.tsTypeScript interface extending JupyterFrontEnd options with shell?: INotebookShell, mimeExtensions?: IRenderMime.IExtensionModule[]
Passed to NotebookApp constructor to configure the application instance with custom shell and MIME extensions
Hidden Assumptions
Things this code relies on but never validates. These are the things that cause silent failures when the system changes.
Expects mimeExtensions array from package.json to be processed sequentially and assumes each extension object has the required structure for createRendermimePlugins() but only checks if the field exists
If this fails: If a MIME extension has malformed structure or missing required fields, createRendermimePlugins() will fail at runtime with cryptic errors, potentially breaking the entire application startup
app/rspack.config.js:mimeExtensions
Assumes options.mimeExtensions is an array of IRenderMime.IExtensionModule objects but only checks if the field exists, not its shape or contents
If this fails: If mimeExtensions contains objects missing required fields like 'id' or 'rendererFactory', createRendermimePlugins() will throw during plugin creation, causing application initialization to fail
packages/application/src/app.ts:NotebookApp.constructor
Assumes widget.context.path is always a valid file path and that PathExt.extname() will return a meaningful extension, but never validates the path format or handles edge cases like empty paths or paths without extensions
If this fails: If a widget has an invalid or empty context.path, the route determination logic fails silently, potentially opening documents in the wrong interface (notebook vs editor) or generating malformed URLs
packages/docmanager-extension/src/index.ts:opener.open
Assumes widget.context.save() will complete successfully before opening in new tab, but doesn't handle save failures or timeouts
If this fails: If save fails due to network issues or permission problems, the new tab opens with stale notebook data, potentially losing kernel info or recent changes without user awareness
packages/docmanager-extension/src/index.ts:opener.open
Expects plugins[page] structure to contain either boolean true or arrays, but template helper list_plugins() will generate malformed JavaScript if plugins contain other data types like objects or strings
If this fails: If package.json has malformed plugin metadata (e.g., plugins.notebook['@some/extension'] = 'config'), the generated template produces invalid JavaScript, breaking application startup with syntax errors
app/rspack.config.js:plugins object parsing
Assumes filesystem write operations are atomic and that concurrent writes to the same package.json won't corrupt the file
If this fails: In parallel build scenarios or with file watchers, multiple processes writing the same package.json simultaneously can result in truncated or corrupted JSON files, breaking subsequent builds
buildutils/src/utils.ts:writePackageJson
Assumes all dependency packages have readable package.json files in their root directories and that Node.js module resolution will find them correctly
If this fails: If a dependency is symlinked, has non-standard structure, or package.json is missing, the build fails with ENOENT errors that don't clearly indicate which package caused the problem
app/rspack.config.js:require(path.join(name, 'package.json'))
Hardcodes that .ipynb files always use 'notebooks' route and other files use 'edit' route, but doesn't account for custom factory preferences or server configuration that might override this routing
If this fails: Users with custom document factories or server configurations may find their files consistently opening in the wrong interface, with no clear way to fix the routing mismatch
packages/docmanager-extension/src/index.ts:route determination
Assumes workspace contains a reasonable number of packages and that getLernaPaths() can read all package.json files in memory without performance issues
If this fails: In very large monorepos with hundreds of packages, this synchronous file reading approach can cause build tools to hang or run out of memory during workspace scanning
buildutils/src/utils.ts:getWorkspacePackages
Assumes notebookShell.currentWidget is always either null or a valid Widget instance, and that addClass/removeClass operations are safe to call repeatedly
If this fails: If currentWidget becomes a proxy object or widget in an invalid state, addClass/removeClass could throw errors, breaking the search functionality UI feedback
packages/documentsearch-extension/src/index.ts:transformWidgetSearchability
System Behavior
How the system operates at runtime — where data accumulates, what loops, what waits, and what controls what.
Data Pools
Maps file types to widget factories and model factories, stores available document types and their handlers
Stores all registered plugins with their dependencies and activation status, manages plugin lifecycle
Webpack/rspack generated bundles and assets that are served to the browser, includes federated modules
Feedback Loops
- Hot Module Replacement (auto-scale, balancing) — Trigger: File changes during development. Action: Rspack rebuilds changed modules and pushes updates to browser. Exit: Development server stops.
- Plugin Dependency Resolution (convergence, balancing) — Trigger: Application startup. Action: Repeatedly attempt to activate plugins whose dependencies are now available. Exit: All plugins activated or dependency deadlock detected.
Delays
- Bundle compilation (compilation, ~10-30 seconds) — Application cannot start until all modules are bundled and federated
- Extension loading (async-processing, ~1-3 seconds) — UI features become available progressively as extensions load
Control Points
- expose_app_in_browser (feature-flag) — Controls: Whether the notebook application exposes itself for browser access. Default: true
- Plugin inclusion (architecture-switch) — Controls: Which plugins get bundled into the final application. Default: All defined plugins
- Module federation remotes (architecture-switch) — Controls: Which external modules can be dynamically loaded at runtime. Default: Extension packages
Technology Stack
Main build tool that bundles TypeScript and assets using webpack-compatible configuration with module federation support
Provides the core JupyterFrontEnd class and plugin system that this notebook application extends
Primary language for all application logic, extension definitions, and type safety across the plugin system
Template engine for generating JavaScript entry points that dynamically load plugins based on configuration
Widget toolkit providing the DOM abstraction and layout system for all UI components
Webpack feature used to create federated modules that can be dynamically loaded and composed at runtime
Key Components
- rspack.config.js (orchestrator) — Orchestrates the entire build process using module federation to bundle all extension packages, generates HTML templates, and creates the final application bundle
app/rspack.config.js - NotebookApp (orchestrator) — Main application class that extends JupyterFrontEnd, manages the document registry, registers MIME renderers, and coordinates all extension plugins
packages/application/src/app.ts - NotebookShell (orchestrator) — Custom shell implementation that manages the layout and widget areas specific to the notebook interface, different from JupyterLab's default shell
packages/application/src/shell.ts - getWorkspacePackages (loader) — Discovers all packages in the workspace by scanning directories and reading package.json files, returns structured package information
buildutils/src/utils.ts - writePackageJson (serializer) — Writes package.json data to disk with consistent formatting, only writes if content has changed
buildutils/src/utils.ts - IDocumentWidgetOpener (adapter) — Service that decides how to open documents - notebooks go to the notebook interface, other files open in editors, handles factory selection based on file type
packages/docmanager-extension/src/index.ts - interfaceSwitcher (adapter) — Plugin that adds toolbar buttons for switching between different Jupyter interfaces (Notebook, JupyterLab, NbClassic), handles URL generation and navigation
packages/lab-extension/src/index.ts - TrustedComponent (validator) — Manages notebook trust status, displays trust indicators in the UI, and handles trust-related security decisions for executing notebook cells
packages/notebook-extension/src/trusted.ts
Package Structure
Main build system that bundles all extension packages into the final notebook application using rspack and module federation.
Development utilities for managing the monorepo workspace, including package synchronization and development setup.
Barrel package that imports all notebook extensions to ensure they're bundled together.
Core notebook application class extending JupyterFrontEnd with a custom shell for the notebook interface.
Extension providing application-level services like routing, splash screen, and shell configuration.
Extension adding console functionality with routing support for opening consoles in new tabs.
Extension handling document opening logic, routing notebook files to the notebook interface and other files to editors.
Extension enabling search functionality within notebooks and documents by managing searchable widget classes.
Extension providing help menu with links to documentation and Jupyter resources.
Extension adding interface switcher toolbar buttons to navigate between Notebook, JupyterLab, and NbClassic interfaces.
Extension providing notebook-specific functionality like kernel status display, trusted document handling, and cell execution features.
Extension adding terminal functionality with routing support for opening terminals in new tabs.
Core file browser tree functionality for navigating the notebook file system.
Extension integrating the file browser tree into the notebook interface.
Shared UI components and icons specific to the Jupyter Notebook interface.
Explore the interactive analysis
See the full architecture map, data flow, and code patterns visualization.
Analyze on CodeSeaRelated Fullstack Repositories
Frequently Asked Questions
What is notebook used for?
Bundles JupyterLab components into Jupyter Notebook v7's web interface jupyter/notebook is a 8-component fullstack written in Jupyter Notebook. Data flows through 5 distinct pipeline stages. The codebase contains 85 files.
How is notebook architected?
notebook is organized into 4 architecture layers: Build System, Core Application, Extension Services, UI Components. Data flows through 5 distinct pipeline stages. This layered structure keeps concerns separated and modules independent.
How does data flow through notebook?
Data moves through 5 stages: Package discovery and bundling → Application initialization → Plugin registration and activation → Document routing and opening → Interface rendering and interaction. The system starts with rspack scanning package.json files to discover extensions, then uses module federation to bundle them into a single application. During runtime, the NotebookApp instance loads and activates plugins, which register services and UI components. When users interact with the interface, routing logic determines how to handle different document types - notebooks open in the notebook interface while other files open in appropriate editors. Extensions communicate through JupyterLab's plugin system using dependency injection. This pipeline design reflects a complex multi-stage processing system.
What technologies does notebook use?
The core stack includes rspack (Main build tool that bundles TypeScript and assets using webpack-compatible configuration with module federation support), @jupyterlab/application (Provides the core JupyterFrontEnd class and plugin system that this notebook application extends), TypeScript (Primary language for all application logic, extension definitions, and type safety across the plugin system), Handlebars (Template engine for generating JavaScript entry points that dynamically load plugins based on configuration), @lumino/widgets (Widget toolkit providing the DOM abstraction and layout system for all UI components), Module Federation (Webpack feature used to create federated modules that can be dynamically loaded and composed at runtime). A focused set of dependencies that keeps the build manageable.
What system dynamics does notebook have?
notebook exhibits 3 data pools (Document Registry, Plugin Registry), 2 feedback loops, 3 control points, 2 delays. The feedback loops handle auto-scale and convergence. These runtime behaviors shape how the system responds to load, failures, and configuration changes.
What design patterns does notebook use?
4 design patterns detected: Plugin Architecture, Module Federation, Template Generation, Workspace Monorepo.
Analyzed on April 20, 2026 by CodeSea. Written by Karolina Sarna.