JupyterLab Front End and a Custom Kernel: What Does the Messaging Protocol Actually Guarantee for Rich Output?
0 reputation · 11 Oct 2025, 00:35 UTC
0 reputation · 11 Oct 2025, 00:35 UTC
We are building a custom kernel that implements the Jupyter messaging protocol (JSON messages over ZeroMQ channels, with HMAC signing from the connection file) and want it to work correctly with JupyterLab and the classic Notebook front end without either side knowing about the other beyond the wire contract. Assume recent Jupyter Server and ipykernel-era protocol versions; exact version negotiation behavior may vary and we plan to verify against the connection file's fields.
The documented envelope (header, parent header, metadata, content) and the shell, stdin, control, and IOPub channels are clear enough for basic execute_request / execute_reply flows. What is unclear is the boundary around rich output: when a kernel publishes display_data with multiple MIME representations, and when widget state is synchronized, the specification does not appear to fully pin down rendering priority or state-sync semantics, and the two front ends seem free to display the same output differently.
Specifically:
31275 reputation · 11 Oct 2025, 07:51 UTC
The Jupyter messaging protocol does not guarantee a specific MIME-type priority for display_data, nor does it dictate how widget state is synchronized. Those decisions are left to the front end. A minimal kernel that works with both JupyterLab and the classic Notebook must implement the core request/reply pairs for kernel info, execution, and shutdown. Widget-related comm_* messages, inspection, completion, and completeness checks are widely expected but not strictly required for basic execution. When the front end advertises an older protocol version than the kernel supports, the kernel should restrict itself to the features defined by the version it advertises in kernel_info_reply and avoid using newer message types or fields.
display_data and update_display_data carry a MIME-bundle (a mapping of MIME type to data). The spec does not define an ordering or fallback rule.kernel_info_request with protocol_version, implementation, implementation_version, and banner.status (busy/idle), stream, error, and display_data (or update_display_data) as appropriate.shutdown_request must be answered with shutdown_reply.JupyterLab and the classic Notebook each maintain their own MIME-type preference lists (e.g., JupyterLab favours application/vnd.jupyter.widget-view+json then text/html then image/svg+xml then image/png then text/plain; the classic Notebook uses a different ordering). Because the protocol does not enforce priority, the same display_data payload can render differently in the two front ends. Widget state synchronization uses the comm_open, comm_msg, and comm_close messages on IOPub and shell; whether those messages are acted upon depends on the presence of a widget manager extension in the front end, which is not guaranteed by the wire contract. If no widget manager is present, comm traffic is silently ignored.
kernel_info_reply your kernel sends: confirm the protocol_version field matches the oldest version you intend to support.display_data message containing identical content for text/plain, text/html, and image/png. Observe which representation each front end renders; this reveals the front end's priority list.comm_open with a custom target ID and a subsequent comm_msg. Verify whether JupyterLab's widget manager processes the message while the classic Notebook ignores it (or vice versa) to confirm comm handling depends on front-end extensions.protocol_version (e.g., 5.3) and ensure you do not send any message types or fields introduced after that version. Then run the kernel with a front end that knows only that older version; no protocol errors should appear.If you are unsure what protocol_version your kernel currently advertises in kernel_info_reply, please provide that value. Knowing the exact version determines whether you need to restrict usage of newer features (e.g., fields added after protocol 5.3) to maintain compatibility.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.