I managed to get a simple Comm channel example from classic jupyter notebook for opening a comm from the kernel
to work using jupyterlab machinery. It uses DocumentRegistry.IWidgetExtension in the front end and the sample code to set up the Comm from the for the above example looks like the following in index.ts file.
IDisposable, DisposableDelegate
} from '@phosphor/disposable';
JupyterLab, JupyterLabPlugin
} from '@jupyterlab/application';
} from '@jupyterlab/docregistry';
NotebookPanel, INotebookModel
} from '@jupyterlab/notebook';
import { myFunction } from './myModule'
* The plugin registration information.
const plugin: JupyterLabPlugin<void> = {
* A notebook widget extension to try things out.
class ExperimentalExtension implements DocumentRegistry.IWidgetExtension<NotebookPanel, INotebookModel> {
* Create a new extension object.
createNew(panel: NotebookPanel, context: DocumentRegistry.IContext<INotebookModel>): IDisposable {
Promise.all([panel.ready, panel.session.ready, context.ready]).then(function() {
const session = context.session;
const kernelInstance = session.kernel;
//const notebook = panel.notebook;
kernelInstance.registerCommTarget('my_comm_target', (comm) => {
//comm.onMsg = (msg) => {console.log("onMsg : "+msg.content.data);comm.send(msg.content.data);};
comm.onClose = (msg) => {console.log("onClose");};
return new DisposableDelegate(() => {});
* Activate the extension.
function activate(app: JupyterLab) {
app.docRegistry.addWidgetExtension('Notebook', new ExperimentalExtension());
console.log('Test JupyterLab extension jupyterlab_expext is activated!');
function handler (msg: any) {
console.log("handler onMsg : " + msg.content.data);
if (msg.content.data['foo'] == 10) {
console.log("foo == 10");
* Export the plugin as default.
I put the kernel code from the example for setting up a comm channel in a jupyterlab notebook cell and tested that I get bidirectional communication.
from ipykernel.comm import Comm
# Use comm to send a message from the kernel
my_comm = Comm(target_name='my_comm_target', data={'foo': 1})
# Add a callback for received messages.
# Use msg['content']['data'] for the data in the message
msg2 = msg['content']['data']
The contents of element with id "demo" get changed to "Paragraph changed" when you execute this code in a notebook cell.
The above example demonstrates basic functionality of setting up a Comm channel in jupyterlab and manipulating HTML in output cell in notebook from typescript code in jupyterlab extension.