Stop Switching IDEs! Run MATLAB Inside Jupyter Now
What if I told you that every time you alt-tab between MATLAB and your Jupyter workflow, you're bleeding productivity? Here's the painful truth most data scientists and engineers refuse to admit: we've built our entire Python-centric notebook ecosystem around Jupyter, yet we're still forced to maintain separate MATLAB installations for signal processing, control systems, and numerical computing. The context switching is brutal. The file format incompatibilities are maddening. And don't get me started on trying to share reproducible research that spans both ecosystems.
But what if there was a way to execute MATLAB code directly inside your Jupyter notebooks—no copy-pasting, no format conversions, no mental context switching whatsoever?
Enter jupyter-matlab-proxy, the official MathWorks integration that's quietly revolutionizing how computational researchers work. This isn't some hacky third-party bridge held together with duct tape and hope. This is official MATLAB integration for Jupyter, built and maintained by the same engineers who create MATLAB itself. And it's about to change everything you thought you knew about mixing Python and MATLAB workflows.
Ready to eliminate the friction forever? Let's dive deep into how this tool works, why it's trending among top engineering teams, and exactly how to set it up in minutes—not hours.
What is jupyter-matlab-proxy?
jupyter-matlab-proxy is the official MATLAB Integration for Jupyter developed and maintained by MathWorks, the creators of MATLAB themselves. Released as an open-source Python package distributed through PyPI, this tool serves as a bridge between the Jupyter ecosystem and MATLAB's computational engine, enabling seamless execution of MATLAB code within Jupyter notebooks, JupyterLab, and JupyterHub environments.
The repository lives at github.com/mathworks/jupyter-matlab-proxy and has been actively developed since 2021, with continuous updates through 2025. What makes this integration particularly significant is its official status—unlike community-driven alternatives that often break with MATLAB updates or lack support for newer features, this proxy is engineered to maintain parity with MATLAB's evolving capabilities.
The package operates through a sophisticated architecture: it implements a Jupyter kernel that communicates with MATLAB's engine API, wrapped in a web proxy that handles the browser-based MATLAB desktop environment. This dual-mode operation is what sets it apart—you're not just getting code execution, you're getting the full MATLAB development environment accessible through your browser, launched directly from your Jupyter interface.
Why is it trending now? Three converging forces: the explosion of JupyterHub deployments in academic and enterprise settings, the growing demand for reproducible computational research that spans multiple languages, and MathWorks' strategic push to position MATLAB as interoperable rather than isolated. The recent addition of Windows support in v0.6.0 dramatically expanded its addressable market, while Python 3.13 compatibility keeps it current with modern data science stacks.
Perhaps most telling is the PyPI download trajectory—thousands of monthly installs suggest this has moved beyond early adopters into mainstream engineering and research workflows. When MathWorks itself invests engineering resources in Jupyter integration, the message is clear: the future of technical computing is multilingual, and MATLAB intends to participate fully.
Key Features That Make This Integration Insane
The jupyter-matlab-proxy package delivers capabilities that would have seemed impossible just a few years ago. Let's dissect what makes this integration genuinely powerful:
Dual-Mode Operation: Kernel + Desktop
At its core, the package provides two distinct but complementary interfaces. The MATLAB Kernel enables code execution within notebook cells—complete with tab completion, rich outputs, and magic commands. But the real secret weapon is the browser-based MATLAB desktop, which opens in a new tab and gives you access to the full IDE: the command window, workspace browser, variable editor, and all the interactive debugging tools MATLAB users depend on.
Rich Output Rendering
The kernel doesn't just return text. It renders inline static plot images directly in notebook cells, displays LaTeX-formatted symbolic expressions for mathematical clarity, and—starting with MATLAB R2024a—formats tables using HTML instead of crude ASCII art. This last improvement transforms the visual experience from terminal-era spartan to modern data presentation.
Advanced Notebook Features
The implementation includes sophisticated capabilities that power users crave: workspace sharing across notebooks (with the option to isolate via %%matlab new_session), local function definitions within cells (R2022b+), and a magic command system (%%lsmagic to discover, custom implementations possible). The %%matlab new_session magic is particularly crucial for production workflows where notebook isolation prevents cross-contamination of workspace state.
Multi-Platform & Multi-Environment Support
Linux, macOS, Windows, and even WSL 2—this isn't a Linux-only toy. The package integrates with JupyterHub for multi-user deployments, The Littlest JupyterHub (TLJH) for classroom settings, and VS Code's Jupyter extension for IDE-native workflows. Simulink programmatic access is supported, with VNC-based GUI access available through a companion package for model visualization.
Syntax Highlighting & File Editing
JupyterLab 4 users get native MATLAB syntax highlighting in .m file editors, with a dedicated "New MATLAB File" command accessible via CTRL+SHIFT+C. While execution of .m files directly isn't yet supported, the editing experience is polished and productive.
Use Cases Where This Tool Absolutely Dominates
Let's move beyond feature lists to real scenarios where jupyter-matlab-proxy transforms workflows:
1. Reproducible Research Publications
You're writing a paper that combines Python-based machine learning preprocessing with MATLAB's robust signal processing toolbox. Previously: export CSVs, context-switch, pray nothing gets misaligned. Now: single Jupyter notebook with Python cells and MATLAB cells, fully reproducible, with outputs captured for publication. The LaTeX symbolic output rendering alone saves hours of manual equation formatting.
2. University Teaching & JupyterHub Deployments
Engineering departments struggle with MATLAB licensing complexity in shared environments. With jupyter-matlab-proxy on JupyterHub or TLJH, students launch notebooks through a browser—no local MATLAB installation, no version conflicts, no "it works on my machine." Instructors prepare one Docker image, and hundreds of students access identical computational environments. The pedagogical consistency is transformative.
3. Enterprise Data Science Pipelines
Your organization standardized on Jupyter for analytics, but the controls engineering team lives in Simulink. Instead of maintaining parallel infrastructure, deploy jupyter-matlab-proxy to enable cross-functional notebooks where data scientists call MATLAB optimization routines and engineers validate models against Python-processed telemetry data. The %%matlab new_session magic ensures production notebooks don't interfere with interactive exploration.
4. Rapid Prototyping with Full IDE Fallback
Start in a notebook for exploratory data analysis—quick iterations, inline plots, narrative documentation. When complexity demands debugging, variable inspection, or Simulink integration, click "Open MATLAB" and continue in the full desktop environment without losing context. It's the best of both worlds: notebook agility and IDE power, zero friction switching between them.
Step-by-Step Installation & Setup Guide
Let's get you running. This guide covers the complete setup from zero to executing MATLAB in Jupyter.
Prerequisites Check
First, verify your system meets requirements:
# Confirm MATLAB is on your system PATH
which matlab
# Verify Python version (3.10, 3.11, 3.12, or 3.13)
python --version
Linux users need X Virtual Frame Buffer:
# Debian/Ubuntu systems
sudo apt install xvfb
# RHEL-based systems
sudo yum install xorg-x11-server-Xvfb
Install from PyPI (Recommended)
The fastest path to productivity:
# Install the proxy package
python -m pip install jupyter-matlab-proxy
# Register the MATLAB kernel with Jupyter
install-matlab-kernelspec
The install-matlab-kernelspec command is critical—it registers the MATLAB kernel with Jupyter's kernel discovery system, making "MATLAB" appear in your notebook's language selector.
Build from Source (Developers & Customizers)
Need the bleeding edge or want to modify behavior? Requires Node.js 18+:
# Clone the repository
git clone https://github.com/mathworks/jupyter-matlab-proxy.git
cd jupyter-matlab-proxy
# Install in development mode
python -m pip install .
# Register the kernel
install-matlab-kernelspec
Install Jupyter Environment
If you haven't already:
# For classic Jupyter Notebook
python -m pip install notebook
# For modern JupyterLab (recommended, supports syntax highlighting)
python -m pip install jupyterlab
Launch and Verify
# Start your preferred environment
jupyter notebook # Classic interface
jupyter lab # Modern interface (recommended)
After installation, you'll see new MATLAB options in your Jupyter interface—both the MATLAB Kernel for notebooks and the "Open MATLAB" button for the desktop environment.
Licensing Configuration
Critical first-run step: When you first execute MATLAB code or open the desktop, a licensing dialog appears. Have your MathWorks account credentials or network license server details ready. The initial MATLAB session startup can take a few minutes as components initialize—this is normal, not an error.
REAL Code Examples from the Repository
Let's examine actual usage patterns from the official documentation, with detailed explanations of what's happening under the hood.
Example 1: Basic MATLAB Kernel Execution
The simplest possible start—creating a notebook and running MATLAB code:
% In a Jupyter cell with MATLAB kernel selected
% This executes directly in MATLAB's engine
A = [1 2; 3 4; 5 6]; % Create a 3x2 matrix
B = A' * A; % Matrix multiplication: transpose then multiply
[eigenvectors, eigenvalues] = eig(B); % Eigendecomposition
disp('Eigenvalues of B:');
disp(eigenvalues);
What's happening: The jupyter-matlab-proxy kernel intercepts this code, forwards it to the MATLAB engine via the MATLAB Engine API for Python, captures all output streams, and returns them to the notebook cell. The workspace variable A persists for subsequent cells—this is the shared session model that enables incremental development. The kernel handles the JSON messaging protocol between Jupyter's frontend and MATLAB's computational backend, translating MATLAB's output formatting into Jupyter's display system.
Example 2: Isolated Session with Magic Commands
When you need workspace isolation—critical for reproducible notebooks:
%%matlab new_session
% This magic command creates a dedicated MATLAB process for this notebook
% Other notebooks won't see or affect this workspace
% Define a complex workflow without contamination risk
data = load('experiment_data.mat');
processed = preprocess(data.raw_signal);
[peaks, locations] = findpeaks(processed, 'MinPeakHeight', 0.5);
% Visualize inline
plot(processed);
hold on;
plot(locations, peaks, 'rv');
hold off;
The magic system explained: %%matlab new_session is a cell magic—it modifies how the entire cell executes. Without it, all notebooks on the same Jupyter server share one MATLAB process (efficient for memory, dangerous for reproducibility). With it, you get process isolation at the cost of additional memory. Run %%lsmagic in any cell to discover all available magics, or implement custom ones for domain-specific workflows.
Example 3: Local Functions in Cells (R2022b+)
Modern MATLAB versions enable modular code within notebooks:
% Main computation in the cell body
signal = randn(1000, 1);
filtered = applyCustomFilter(signal, 0.1, 4);
% Local function definition at cell end
function y = applyCustomFilter(x, cutoff, order)
% Butterworth lowpass filter implementation
[b, a] = butter(order, cutoff);
y = filtfilt(b, a, x); % Zero-phase digital filtering
end
Why this matters: Previously, notebook cells were limited to scripts—no function definitions. This forced users to either externalize functions to .m files (breaking the self-contained notebook ideal) or use anonymous functions with limited capability. Local functions enable true literate programming where narrative, main analysis, and utility functions coexist in one readable document. The kernel parses the cell, extracts the local function, and makes it available within that cell's scope.
Example 4: Rich Output Rendering
Demonstrating the advanced display capabilities:
% Symbolic mathematics with LaTeX output
syms x y
f = x^2 + 3*x*y + y^2;
gradient_f = gradient(f, [x, y]);
% In R2024a+, this renders as beautifully typeset LaTeX
% In earlier versions, you get ASCII representation
% Table with HTML formatting (R2024a+)
T = table(rand(5,1), randi(100,5,1), randn(5,1), ...
'VariableNames', {'Probability', 'Count', 'Deviation'});
disp(T);
The rendering pipeline: For symbolic expressions, the kernel captures MATLAB's internal LaTeX representation and passes it through Jupyter's MathJax renderer. For tables, R2024a+ generates HTML markup that Jupyter displays as styled tables—prior versions fall back to monospaced ASCII. This version-dependent feature matrix means enterprise deployments should standardize on R2024a or later for optimal notebook aesthetics.
Advanced Usage & Best Practices
After basic setup, these strategies separate casual users from power users:
Session Management Strategy: Use shared sessions (default) for exploratory work where you want variables persistent across notebooks. Switch to %%matlab new_session for any notebook destined for production, publication, or sharing. Document which mode each notebook uses in its header markdown.
Docker Deployment for Teams: For consistent environments, build a Docker image with both Python/Jupyter and MATLAB pre-installed. The official MATLAB container images provide base layers with dependencies resolved. Pin your jupyter-matlab-proxy version to avoid surprise updates breaking workflows.
VS Code Integration: The package works with VS Code's Jupyter extension—install jupyter-matlab-proxy in your VS Code Python environment, and MATLAB appears as a kernel option alongside Python and Julia. This is often smoother than browser-based JupyterLab for developers already living in VS Code.
Simulink Automation: While GUI features require the VNC companion package, programmatic Simulink workflows work directly: sim('myModel'), set_param, get_param—all execute in notebook cells. Log simulation data to MATLAB workspace variables, then analyze with Python in subsequent cells.
Performance Optimization: MATLAB's initial startup is slow (30-120 seconds). In JupyterHub deployments, use pre-spawned MATLAB processes or accept the first-cell delay. For compute-heavy loops, consider whether the data transfer overhead between Python and MATLAB justifies mixed-language implementation versus pure MATLAB execution.
Comparison with Alternatives
| Feature | jupyter-matlab-proxy |
MATLAB Engine API (Direct) | Octave Kernel | File-Based Exchange |
|---|---|---|---|---|
| Official MathWorks Support | ✅ Yes | ✅ Yes | ❌ No | N/A |
| Browser-Based MATLAB Desktop | ✅ Full IDE | ❌ None | ❌ None | ❌ None |
| Jupyter Kernel Protocol | ✅ Native | ❌ Manual wrapping | ✅ Native | ❌ None |
| Rich Outputs (Plots, LaTeX) | ✅ Built-in | ⚠️ Manual | ⚠️ Limited | ❌ None |
| Multi-User (JupyterHub) | ✅ Designed for | ❌ Complex | ✅ Possible | ❌ None |
| Syntax Highlighting | ✅ JupyterLab 4 | N/A | ✅ Basic | N/A |
| Licensing | Standard MATLAB | Standard MATLAB | GPL (free) | N/A |
| Setup Complexity | Low (pip install) | Medium | Low | High (manual) |
The verdict: Direct MATLAB Engine API calls from Python offer more flexibility but require you to build all Jupyter integration yourself. Octave provides free MATLAB-like syntax but lacks compatibility with MATLAB toolboxes and Simulink. File-based exchange (CSV, MAT-files) is fragile and non-interactive. For teams already invested in Jupyter and MATLAB licensing, jupyter-matlab-proxy is the clear optimal path—it eliminates integration overhead while preserving full access to both ecosystems.
FAQ: Your Burning Questions Answered
Q: Do I need a MATLAB license to use jupyter-matlab-proxy?
Yes. The package is free and open-source, but it requires MATLAB R2020b or later installed and licensed on your system. You can open notebooks containing MATLAB code without MATLAB installed, but execution requires a valid license—individual, academic, or network.
Q: Can I mix Python and MATLAB in the same notebook?
Not directly in one kernel, but yes in practice. Use multiple kernels in Jupyter—Python cells in a Python kernel, MATLAB cells in a MATLAB kernel—or use the MATLAB Engine API from Python for tighter integration. The most common pattern: Python for data loading/preprocessing, MATLAB for specialized analysis, Python for visualization and reporting.
Q: Why is my first MATLAB execution so slow?
MATLAB's initial startup involves license verification, path initialization, and Java runtime startup. This is inherent to MATLAB, not the proxy. Subsequent executions in the same session are fast. For JupyterHub, consider pre-warming MATLAB processes.
Q: Does this work with Simulink GUI features?
Programmatic Simulink commands work directly. For GUI features (model visualization, block diagram editing), use the companion MATLAB Jupyter VNC Solution which provides VNC-based Linux desktop access.
Q: Can I use this on Windows?
Yes, Windows support was added in v0.6.0. Earlier versions were Linux/macOS only. WSL 2 is also supported with a dedicated installation guide.
Q: How do I troubleshoot kernel connection issues?
Start with the official troubleshooting guide. Common fixes: verify which matlab returns a path, check licensing dialog wasn't dismissed, ensure install-matlab-kernelspec ran successfully, and confirm Python version compatibility (3.10-3.13).
Q: Is the MATLAB workspace shared across all my notebooks?
By default, yes—multiple notebooks share one MATLAB process for efficiency. Use %%matlab new_session in any cell to create an isolated workspace for that notebook. This is documented in the kernel architecture README.
Conclusion: The Future Is Multilingual—Embrace It
The artificial wall between Python's data science ecosystem and MATLAB's engineering computing dominance has finally crumbled. jupyter-matlab-proxy isn't a compromise or a hack—it's official, engineered, and actively maintained integration that respects both platforms' strengths while eliminating the friction of using them together.
For researchers, this means reproducible publications that leverage the best tools for each analysis phase. For educators, it means streamlined infrastructure that puts students first. For enterprise teams, it means breaking down silos between data scientists and domain engineers.
The setup is genuinely simple—pip install and install-matlab-kernelspec gets you started in minutes. The capabilities are genuinely powerful—full MATLAB desktop in your browser, rich outputs, magic commands, and multi-environment support. And the trajectory is clear: MathWorks is investing in interoperability, and this package is their flagship bridge to the Jupyter universe.
Stop context-switching. Stop maintaining parallel workflows. Stop pretending you don't need both Python and MATLAB.
Install jupyter-matlab-proxy today from github.com/mathworks/jupyter-matlab-proxy, run your first MATLAB cell in Jupyter, and experience what seamless multilingual computing actually feels like. Your future self—the one not alt-tabbing between IDEs at 2 AM—will thank you.
Have you integrated MATLAB into your Jupyter workflow? What mixed-language challenges are you solving? Share your experience in the comments, and don't forget to star the repository if this guide helped you get started.