Git-free marimo notebook sharing via GitHub
Project description
⚓ mooring
Git-free marimo notebook sharing via GitHub.
Mooring is a single-file app (mooring.pyz / mooring.exe) that lets a team
of data analysts pull, edit, and push marimo notebooks stored in a shared
GitHub repo — without git installed on their machines. All sync happens
over the GitHub REST API; the only requirement on an analyst's machine is
Python 3.12.
Double-clicking the app opens a local browser hub: log in to GitHub with a one-time device code, see every team notebook with its sync status, pull the latest, open notebooks in the bundled marimo editor, and push your changes back — one commit per file, with conflicts detected and resolved per file (never silently overwritten).
Built with moonlit.
How it works
- One shared team repo (e.g.
your-org/notebooks) holdsnotebooks/anddata/folders. Everyone pulls from and pushes to it. - No git anywhere. Pull walks the repo tree via the GitHub Git Data API and downloads only changed blobs; push uses the Contents API with the file's last-known SHA, so GitHub itself rejects writes that would clobber someone else's change.
- Three-way change detection. Mooring computes git blob SHAs locally and keeps a manifest of what was last synced, so it always knows whether a file is modified locally, changed remotely, or conflicted.
- Conflicts are explicit. Pull never overwrites local edits; push blocks
conflicted files. The hub offers per-file resolution: Use remote,
Keep both, or Push as copy (publishes your version under
name-<your-github-login>.py). - Frozen package stack. Notebooks can import anything bundled into the
artifact:
polars,altair,plotly,openpyxl,fastexcel,requests(plus the standard library). There is no pip at runtime.
For analysts: install & use
- Install Python 3.12 (tick "Add python.exe to PATH").
- Get
mooring.exe(ormooring.pyz) from your admin and put it anywhere, e.g. your Desktop. - Run it (
mooring.exe, orpython mooring.pyz). Your browser opens the hub. - Click Log in with GitHub, enter the code shown at github.com/login/device.
- Pull to fetch the team's notebooks, Open to edit one in marimo, New notebook to start fresh, Push to share your work.
Notebooks live in Documents\mooring\<repo>\notebooks\; data files your
notebooks read go in ...\<repo>\data\ and sync the same way.
The first launch takes a minute while the app unpacks itself to a local cache; later launches are fast.
CLI (optional)
Everything the hub does is also available from a terminal:
python mooring.pyz login | logout | whoami
python mooring.pyz status
python mooring.pyz pull [--theirs | --keep-both]
python mooring.pyz push [paths...] [-m "message"]
python mooring.pyz open notebooks/sales.py
python mooring.pyz new sales-analysis
python mooring.pyz selftest
For admins: set up a team
-
Create the shared repo, e.g.
your-org/notebooks, with emptynotebooks/anddata/folders. Don't enable git-LFS (the API would deliver pointer files). -
Register a GitHub OAuth app (Settings → Developer settings → OAuth apps → New). Any homepage/callback URL works; then enable Device Flow on the app. Copy the client id — there is no secret to manage.
- If the repo lives in an org with third-party-app restrictions, an org owner must approve the OAuth app.
-
Bake the config: edit
src/mooring/config_default.tomlwith the client id, owner, repo, and branch. -
Build (requires uv):
uv sync uv run pytest uvx --python 3.13 moonlit build -e mooring.cli:main -o dist/mooring.pyz --python-version 3.12 uvx --python 3.13 moonlit build -e mooring.cli:main -o dist/mooring.exe --windows-exe --python-version 3.12For machines with no Python at all, build a folder bundle with embedded CPython instead:
uvx --python 3.13 moonlit build -e mooring.cli:main -o dist/mooring-bundle --bundle-python --python-version 3.12 -
Distribute the artifact (file share, email, GitHub release — the
.github/workflows/release.ymlworkflow builds and attaches artifacts on everyv*tag).
Users without a baked config get a one-time setup form in the hub instead;
their values are stored in %APPDATA%\mooring\config.toml.
Changing the bundled notebook packages
Edit dependencies in pyproject.toml, uv sync, rebuild, redistribute.
Notebooks can only import what's frozen into the artifact.
Development
uv sync # install everything
uv run pytest # unit tests (no network needed)
uv run ruff check src tests # lint
uv run mooring hub # run the hub from source
uv run python tests/manual_editor_check.py # editor-subprocess smoke test
Layout: src/mooring/ — cli.py (entry point; also sets PYTHONPATH so the
marimo subprocess works from inside the packaged artifact), auth.py (device
flow + keyring), github.py (REST client), gitsha.py/manifest.py/sync.py
(the three-way sync engine), editor.py (marimo subprocess manager),
hub/ (Starlette app + static frontend).
To integration-test sync against a real repo, set MOORING_TOKEN (a PAT
works) plus MOORING_OWNER/MOORING_REPO/MOORING_CLIENT_ID and use the
CLI against a scratch repository.
Constraints & notes
- Python version is pinned. A
.pyz/.exebuilt for 3.12 needs the user to have Python 3.12.x; moonlit shows a clear error otherwise. The--bundle-pythonbuild escapes this entirely. - File sizes: pushes warn at 10 MB and refuse at 45 MB per file (GitHub Contents API limit). Keep big datasets out of the repo.
- Tokens are stored in the OS credential store (Windows Credential
Manager);
repo-scoped OAuth tokens grant access to all repos the user can reach — use a dedicated machine account org if that's a concern. - Artifact size is ~110 MB (marimo + polars + plotly + altair). First
run extracts to
%LOCALAPPDATA%\moonlit\; old versions' caches can be deleted freely.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mooring-0.1.0.tar.gz.
File metadata
- Download URL: mooring-0.1.0.tar.gz
- Upload date:
- Size: 61.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7a0ab8a84f2862ebea50a80df267e8a3fe2c169b15cc35012366b567ff5b491
|
|
| MD5 |
61192dd2721dd5c93d2f685a157828d1
|
|
| BLAKE2b-256 |
34a4d8e66fa0c2d7d247fdb0adb96e1aba4180422774ee12f4596ca90302e153
|
File details
Details for the file mooring-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mooring-0.1.0-py3-none-any.whl
- Upload date:
- Size: 29.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f302ed728216838aebb95340bfb001ac83338e567625b9302b415aba2d30052
|
|
| MD5 |
fafa0ce9f85f105226bf7a966f9c6582
|
|
| BLAKE2b-256 |
a87d942a2f2d36e4d77e2c0d2c3fa8149d9eb34d7e9155b1001d546ae5e1f227
|