jp-kernel is an npm module for implementing a Jupyter kernel that interacts with a Node.js session.

jp-kernel is a spin-off library from IJavascript, a Javascript kernel for the Jupyter notebook. It is currently used to implement the following kernels:


  • Version 2.0.0 require Node.js v6 or above so that we can use jmp@2.

  • Version 1.3.0 (unpublished) use jmp@2 if compatible with the version of Node.js.

  • Version 1.2.0 implements message clear_output.

  • Version 1.1.0 ensures metadata is defined in display_data messages.

  • Version 1.0.0 (stable API) handles flag --hide-execution-result.

  • Version 0.1.5 handles input_request and input_reply messages.

  • Version 0.1.4 handles display_data and update_display_data messages.

  • Version 0.1.0 depends on jmp@0.7.2, and jmp@0.7.2 depends on zeromq (which provides prebuilt bindings to the ZMQ library and is now maintained by the zeromq organisation).

  • Version 0.0.1 is the initial release based on IJavascript v5.0.13.


The latest stable release is published on npm and can be installed by running:

npm install jp-kernel

The master branch in the github repository provides the latest development version and can be installed by:

git clone https://github.com/n-riesco/jp-kernel.git
cd jp-kernel
npm install


The source code documentation generated using JSDoc can be found here.

For real examples of usage, see the source documentation for:


First of all, thank you for taking the time to contribute. Please, read CONTRIBUTING.md and use the issue tracker for any contributions: support requests, bug reports, enhancement requests, pull requests, ...

Next API v2

The jp-kernel API in the initial release v0.0.1 came into existence by a process of evolution. I want to take the opportunity that distributing jp-kernel as a package offers to design a new API. Below is a preview of what I have in mind:

class Kernel {
    constructor(config) {
        this.config = config;

        this.executionCount = 0;

        this.session = new Session({
            cwd: this.config.cwd,
            parser: this.config.parser,
            transpile: this.config.transpile,


    _init(initCB) {}
    interrupt(interruptCB) {}
    destroy(destroyCB) {}
    restart(restartCB) {}

    _onShellMessage(message) {}
    _onControlMessage(message) {}
    _onIOPubMessage(message) {}
    _onHBMessage(message) {}
class KernelV4 extends Kernel {
    onStdout(data) {}
    onStderr(data) {}
    onShell_xxx(request) {}
class KernelV5 extends Kernel {
    onStdout(data) {}
    onStderr(data) {}
    onShell_xxx(request) {}
class Config {
    constructor(kernelConfig) {
        this.hideUndefined = kernelConfig.hideUndefined;
        this.initSession = kernelConfig.initSession;
        this.initScripts = kernelConfig.initScripts;
        this.kernelInfoReply = kernelConfig.kernelInfoReply;
        this.protocolVersion = kernelConfig.protocolVersion;

        this.connection = kernelConfig.connection;
        this.parser = kernelConfig.parser;
class Connection {
    constructor(connectionConfig) {
        this.config = connectionConfig;
        this.socket = {
            control: new jmp.Socket("router", scheme, key),
            shell: new jmp.Socket("router", scheme, key),
            iopub: new jmp.Socket("pub", scheme, key),
            hb: zmq.createSocket("rep"),

    connect(listeners) {}
    disconnect() {}
class Parser{
    constructor() {
        throw new Error("Cannot construct an abstract class");

    getIdentifier(code, position) {
        throw new Error("Not implemented");

    validate(code) {
        throw new Error("Not implemented");