Publishing a Notebook

On this page
  1. Where the files go
  2. 1. Put the data in public
  3. 2. Export
  4. 3. Make docs/.nojekyll
  5. 4. Commit and push
  6. 5. Turn on GitHub Pages
  7. Your address
  8. Check that it is live
  9. Limits
  10. When it does not work

Publishing puts a notebook at its own web address, where anybody can open it in a browser with nothing installed. marimo export html-wasm turns the notebook into a folder of web files. GitHub Pages serves that folder from your course repository at no cost, and the notebook runs in the visitor's browser.

The steps use Mini Project 1, in a folder named mp1. For another project, use that project's folder name wherever mp1 appears.

Where the files go#

<course-code>/
├── docs/
│   ├── .nojekyll          an empty file, made once
│   └── mp1/               the export, which you never edit by hand
└── projects/
    └── mp1/
        ├── <your-notebook>.py
        └── public/        the data file your notebook reads

GitHub Pages publishes either the top of a repository or a folder named docs. Every notebook you publish needs its own folder inside docs.

1. Put the data in public#

A published notebook can read only the files published with it. The export copies the folder named public that sits beside the notebook, so the file your notebook reads has to go in projects/mp1/public/.

Build the path to it with mo.notebook_location(), which finds that folder on your machine and on the published page:

df = pl.read_csv(str(mo.notebook_location() / "public" / "countries.csv"))

A path written any other way, such as "public/countries.csv" on its own, fails on the published page with FileNotFoundError.

Write the file name with the capitals it has in public. On your computer Countries.csv also opens countries.csv, and on the published page it does not.

If your notebook pulls from an API, save what it pulled as a file in public/, and have the notebook you publish read that file.

2. Export#

In the VS Code terminal, in the root folder of your course repository, run:

uv run marimo export html-wasm projects/mp1/<your-notebook>.py -o docs/mp1

Replace <your-notebook>, angle brackets included, with your notebook's name.

Run the same line again after every change to the notebook. The published page changes only when you export and push again.

3. Make docs/.nojekyll#

Do this once per repository. In the VS Code file list, right-click docs, choose New File, name it .nojekyll, and save it empty.

Without it, GitHub leaves out every file whose name starts with an underscore. The export contains several, and the page never finishes loading. GitHub looks for .nojekyll directly in docs, so the copy the export puts inside docs/mp1/ is not enough.

4. Commit and push#

In GitHub Desktop, the export appears as several hundred new files. Commit them together with the data file and .nojekyll:

  1. Summary: publish mp1
  2. Commit to main
  3. Push origin

5. Turn on GitHub Pages#

Do this once per repository.

  1. In GitHub Desktop, choose Repository → View on GitHub
  2. Click Settings, then Pages in the left column
  3. Under Build and deployment, set Source to Deploy from a branch
  4. Set the branch to main and the folder to /docs, then click Save

Your address#

https://<your-github-username>.github.io/<course-code>/mp1/

The Pages settings page gives the address without mp1/ on the end. That shorter address shows a 404 because there is no index.html directly in docs, so add the folder name. GitHub Pages treats MP1 and mp1 as different folders, so match the capitals in docs.

A project in a repository of its own follows the same steps, with that repository's name in place of <course-code>.

Check that it is live#

  1. Wait up to 10 minutes after you push.
  2. Open the address in a private browser window.
  3. Wait for the first output. The browser loads Python before any cell runs, so it takes a while.
  4. Compare the numbers on the page with the ones in your notebook on your machine.

If the page still shows an earlier version after a push, wait 10 minutes and reload.

Limits#

Anybody can read what you publish. The page contains the notebook's code, and anybody can download the files in public/. Never put an API key in a notebook you publish, and publish only data you are free to share.

No file over 100 MB. GitHub warns about a file over 50 MB and refuses to push one over 100 MB, so a larger dataset cannot be published this way.

When it does not work#

  • The address shows a 404. Check that mp1/ is on the end of the address, that the Pages folder is /docs, and that 10 minutes have passed since the push.
  • The page never finishes loading. docs/.nojekyll is missing. Make it as in step 3, then commit and push.
  • A cell shows FileNotFoundError. The file is not in projects/mp1/public/, or the notebook reads it without mo.notebook_location(). Fix it, export again, and push.

Last updated: Sunday, 11/1/2026