This doesn’t completely address all your issues, but I can tell you what I use as a workflow.
First, I think it is important to think of Jupyter as an application. It should never be part of your project environments: A kernel might be, but Jupyter itself is just some program (that happens to be implemented in Python) that you need to install somewhere on your system. Personally, I use a dedicated Miniforge environment. People get confused by stuff like the IJulia instructions to run notebook()
in your Julia REPL. That might be good if you have a class to teach and you just need things to run, but it just creates a lot of confusion.
So, make sure you have Jupyter installed (on your remote workstation), with all the plugins you like. Then also install IJulia
into your main Julia environment (not your project environments; luckily, Julia is better than Python in that respect). One plugin that’s absolutely essential (and that should be installed alongside Jupyter itself) is Jupytext. This allows you to link your .ipynb
files to .md
or .jl
files that get synchronized automatically.
Now what I’ll do is connect to my remote workstation via ssh (with X-forwarding) and run tmux
. I’ll open the .jl
version of the notebook in neovim
and a Julia REPL side-by side in two tmux windows. I’ll then use vim-slime to send code from the editor to the REPL. This is great for experimentation and to build up a notebook.
I’ll also have a Jupyter Lab server running on the remote workstation where I view the .ipynb
version of the notebooks. I can access that server through SSH with port forwarding. As I said, Jupytext
will make sure that these are synchronized (but you might have to do “reload from disk” sometimes). Once I finish experimenting, I’ll re-run the entire notebook (the .ipynb
version) in Jupyter and save it. I might also work in the notebooks directly for smaller fixes, or if I’m comparing plots, or stuff like that. Those notebooks stay on disk, as something that I can show my boss if he drops in. I’ve also used Quarto to generate “reports” in PDF format from time to time.
So, basically, work in your editor and the REPL via ssh/tmux, and the .ipynb
files automatically get saved as a permanent record of that work.
I’ll commit only the .md
/.jl
versions of the notebooks, not the .ipynb
version, since they’re much more amenable to version control (the original motivation of juypytext
!). The .ipynb
version can also easily be recreated. Nowadays, I usually write myself a Makefile
that regenerates any missing .ipynb
files from a clean checkout.
The resulting repo might look something like this (this is research code, not really meant for public consumption). When a project ends, I’ll zip up the entire folder including all the .ipynb
files with all the plots in them, for archival in addition to the git.