Do you need JupyterHub for your workshop? JupyterLite runs Python in the browser

jupyter
teaching
python
Author

Andrea Zonca

Published

May 18, 2026

You’re organizing a Python workshop or teaching a class that uses Jupyter notebooks. The first question that comes up is almost always the same: how do I get everyone running notebooks without spending an hour on installation?

The traditional answer has been JupyterHub — a server that hosts Jupyter for all your participants. But there’s a simpler option that works for many scenarios: JupyterLite, which runs Python entirely in the browser with zero server infrastructure.

An important caveat: Software Carpentry workshops have an explicit goal that students leave with a functioning local Python installation they can continue using after the workshop. In that case, JupyterLite is not a replacement — the local install is the point. This guide is targeted at the many other workshops and classes that instead want to focus on teaching a specific package or subject and do not care much about the local environment of the students. For those, JupyterLite eliminates the installation hurdle entirely and lets you focus on the content.

JupyterHub: Powerful but Demanding

JupyterHub is the gold standard for multi-user notebook hosting. It gives every participant their own isolated Jupyter server, with full access to the host’s Python environment, filesystem, and computing resources.

When you need JupyterHub:

  • Your workshop requires GPU access or heavy computation
  • Participants need to work with large datasets that don’t fit in browser memory
  • You need persistent storage across sessions
  • You’re running custom kernels (R, Julia, etc.) beyond Python
  • Your code requires network access to external APIs or databases during execution
  • You need to run code that depends on native system libraries not available in WebAssembly

The trade-off? JupyterHub requires a server (cloud VM, Kubernetes cluster, or HPC system), ongoing maintenance, and someone to manage it. If you’re deploying on cloud infrastructure, I’ve written about deploying JupyterHub on OpenStack Magnum with OpenTofu — it works well, but it’s not trivial.

JupyterLite: Zero Server, Zero Installation

JupyterLite takes a completely different approach: it runs a full Python environment compiled to WebAssembly directly in the browser. No server, no installation, no setup time — participants just open a URL and start coding.

JupyterLite is ideal when:

  • You want zero setup time — participants open a link and start coding immediately
  • You’re teaching introductory Python with standard scientific packages
  • Your workshop is short (a few hours) and doesn’t need persistent storage
  • You don’t have infrastructure budget or time to set up a server
  • You want participants to continue practicing at home without installing anything
  • You need offline capability — once loaded, notebooks work without internet

Scientific Python in the Browser

A common concern is whether the browser-based Python environment can handle real scientific computing. Thanks to Pyodide (the Python-in-WebAssembly runtime that powers JupyterLite), many of the most important scientific Python packages work out of the box — including packages with C extensions that have been compiled to WebAssembly:

Package What It Does C Extensions?
NumPy Array computing, linear algebra Yes
SciPy Scientific algorithms, optimization, statistics Yes
Matplotlib Plotting and visualization Yes
Pandas Data manipulation and analysis Yes (via NumPy)
scikit-learn Machine learning Yes

These five packages cover the vast majority of introductory scientific Python curricula. In fact, the entire Software Carpentry Python Novice curriculum — both the Inflammation and Gapminder tutorials — runs perfectly in JupyterLite because it only needs NumPy, Matplotlib, and Pandas.

Other notable packages available in Pyodide include scikit-image, statsmodels, sympy, and astropy. You can check the full list of available packages in the Pyodide documentation.

What Doesn’t Work (Yet)

JupyterLite has some limitations you should be aware of:

  • Network access from Python: The browser security model restricts raw socket access, so packages like astroquery that make direct HTTPS connections won’t work
  • HDF5 support: h5py and pytables are not currently available in Pyodide
  • Very large datasets: Browser memory is limited (typically 2-4 GB per tab)
  • GPU computing: No CUDA or GPU access from WebAssembly
  • Persistent filesystem: Data saved in the notebook disappears when you close the tab (though you can download notebooks)
  • Custom kernels: Only Python (via Pyodide) and JavaScript kernels are available

A Real Example: Software Carpentry Tutorials on JupyterLite

To demonstrate that JupyterLite works for real teaching material, I’ve deployed the Software Carpentry Python tutorials as a live JupyterLite site:

https://zonca.github.io/jupyterlite-carpentry/lab/

This site includes two complete tutorials converted from the original Carpentries markdown episodes into interactive notebooks:

  • Python Novice: Inflammation — Introduction to Python using inflammation data analysis (NumPy, Matplotlib)
  • Python Novice: Gapminder — Introduction to Python using Gapminder GDP data (Pandas, Matplotlib)

The source code for this deployment is at https://github.com/zonca/jupyterlite-carpentry — it uses GitHub Pages with a GitHub Actions workflow that builds the JupyterLite site automatically on every push to main.

How the Deployment Works

The entire deployment is surprisingly simple:

  1. Notebooks and data live in a content/ directory
  2. jupyter lite build --contents content compiles them into a static JupyterLite site
  3. The built _output/ directory is deployed to GitHub Pages via Actions
  4. Participants access the site at https://<username>.github.io/<repo>/lab/

That’s it. No Kubernetes, no Helm charts, no SSL certificates, no user authentication. The entire site is just static files served by GitHub.

GitHub Actions Configuration

The deployment is automated with a simple two-job workflow:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      - run: pip install -r requirements.txt
      - run: make build
      - uses: actions/upload-pages-artifact@v3
        with:
          path: _output

  deploy:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    needs: build
    runs-on: ubuntu-latest
    environment:
      name: github-pages
    steps:
      - uses: actions/deploy-pages@v4

The build job installs the JupyterLite dependencies, runs jupyter lite build, and uploads the generated static site as an artifact. The deploy job takes that artifact and publishes it to GitHub Pages — but only on pushes to main, not on pull requests. The permissions block grants the workflow access to the GitHub Pages API. You also need to enable GitHub Pages in your repository settings and set the Source to “GitHub Actions” (not “Deploy from a branch”).

Decision Guide: JupyterHub or JupyterLite?

Feature JupyterLite JupyterHub
Setup effort Minutes (push to GitHub) Hours to days
Server cost Free (GitHub Pages) Cloud VM costs
Installation None for participants None for participants
Python packages Pyodide subset Full conda/pip
Data size Small (< 100 MB) Unlimited
Computation Browser-only Full server resources
Persistence Download only Persistent home directory
Network access Limited Full
Offline Works after loading Requires connection
Maintenance None Ongoing

My recommendation: Start with JupyterLite for introductory workshops and short courses. If your curriculum fits within the Pyodide package ecosystem (and most introductory Python does), you’ll save enormous amounts of setup time and infrastructure cost. Graduate to JupyterHub only when you need capabilities that the browser can’t provide.

Getting Started

To create your own JupyterLite deployment with custom notebooks:

pip install jupyterlite-pyodide-kernel jupyterlite
jupyter lite build --contents /path/to/your/notebooks
jupyter lite serve

Or fork zonca/jupyterlite-carpentry and replace the notebooks with your own — the GitHub Actions workflow will build and deploy automatically.