By · Founder, Stacktree · Last updated
use case

Share a Jupyter notebook as private HTML.

Export the notebook to HTML, publish to Stacktree, gate the link to your team. Plotly, ipywidgets, matplotlib, and DataFrame previews all render exactly like they did in the notebook — and the URL is private by default.

Get started free

How do you share a Jupyter notebook with your team privately?

Export the notebook to standalone HTML (jupyter nbconvert --to html --embed-images notebook.ipynb), upload the resulting file to Stacktree, and add an email-domain gate or password. Viewers open the link without installing Jupyter, without logging into a hosted Jupyter server, and without exposing the notebook publicly. Re-running the export later and calling update_site swaps the content under the same URL.

The minimal workflow

# 1. Convert
jupyter nbconvert --to html --embed-images analysis.ipynb

# 2. Publish (anonymous, 24-hour link)
curl -F file=@analysis.html https://api.stacktr.ee/sites

# 3. Or publish authenticated for a persistent URL
stacktree publish analysis.html --gate=email:@yourco.com --expire=30d

What renders correctly

  • Plotly / Bokeh / Altair. Interactive charts work — nbconvert embeds the JS bundles.
  • ipywidgets. Static representations are embedded (live interaction requires a kernel; not in scope).
  • matplotlib + seaborn. Rendered as static PNG, embedded inline.
  • pandas DataFrames. HTML tables, styled.
  • LaTeX / MathJax. Renders via the embedded MathJax bundle.
  • Markdown cells. As written.

Why not GitHub Gist or nbviewer?

  • nbviewer is public — anyone with the URL of the underlying .ipynb sees the rendered notebook.
  • Gist works only if the notebook is committed to a Gist (public or "secret" / shareable, but not enforceably private).
  • Stacktree keeps the notebook out of any public surface and lets you layer auth on top.

For data-science teams

The pattern that's worked well: each analyst publishes their notebook output to a Stacktree, gates it to the team's email domain, and posts the link in Slack. When the analysis is re-run with new data, calling update_site replaces the content — the existing Slack message link picks up the new version on refresh. No version sprawl, no "see V3" follow-up post.

FAQ

Frequent questions

How do I share a Jupyter notebook with my team privately? +
Export the notebook to standalone HTML with jupyter nbconvert --to html --embed-images notebook.ipynb, then upload the file to Stacktree. Add an email-domain gate so only @yourco.com viewers can open the link. The notebook's plots, widget output, and DataFrames render exactly as they did in the notebook.
Do Plotly charts and ipywidgets work? +
Yes. nbconvert's HTML export embeds the JS libraries the widgets need; Stacktree serves the file as-is. Plotly, Bokeh, ipywidgets, Altair, and matplotlib (as static PNG) all render in the published page.
What about the kernel? Will viewers be able to re-run cells? +
No — exported HTML is a static snapshot of cell outputs. If you need a live kernel, you want JupyterLite or a hosted Jupyter server, not a static-HTML host.
Can I publish from a notebook directly? +
Yes — from a code cell: !curl -F file=@$(jupyter nbconvert --to html --stdout notebook.ipynb) https://api.stacktr.ee/sites. The response includes the URL.
Is the notebook output really private? +
Every Stacktree URL is unguessable by default. Add a password or email-domain gate per link if the notebook contains sensitive data (customer rows, API responses, model outputs).
How does this compare to nbviewer or GitHub Gist rendering? +
nbviewer and Gist rendering are public-by-default and need the notebook to live on a URL anyone can fetch. Stacktree keeps the notebook private and supports replace-in-place if you re-publish updated runs.
Keep reading

Related guides

References

Sources and further reading

Get your notebook off the public web.

One nbconvert, one curl. Your team opens the link; nobody else can.

Sign up free →