A data portal that serves Marimo notebooks through a Next.js interface. Built on OSO.
# 1. Get an OSO API key at https://www.oso.xyz/start
cp .env.example .env
# Add your key: OSO_API_KEY=your_key_here# 2. Install dependencies
uv sync
cd app && pnpm install &&cd ..
# 3. Export notebooks to static HTMLcd app && pnpm export:notebooks &&cd ..
# 4. Start the dev servercd app && pnpm devOpen http://localhost:3000.
- OSO API key (get one here)
- uv — Python package manager
- Node.js 20+ and pnpm
ddp/
├── notebooks/ # Marimo notebooks (.py)
│ ├── quick-start.py
│ ├── publications.py
│ ├── agent-guide.py
│ ├── data/
│ │ ├── sources/ # Open Dev Data, GitHub Archive, OSS Directory
│ │ ├── models/ # Ecosystems, Repositories, Developers, Commits, Events, Timeseries Metrics
│ │ └── metric-definitions/ # Activity, Alignment, Lifecycle, Retention
│ └── insights/ # 2025 Developer Trends, Lifecycle, Speedrun Ethereum, DeFi Journeys, Retention
├── scripts/
│ └── export_notebooks.py # Exports notebooks to static HTML
├── app/ # Next.js app (UI shell)
│ ├── app/ # Pages (App Router)
│ ├── components/ # Sidebar, MarimoIframe
│ └── public/notebooks/ # Exported HTML (generated, gitignored)
└── pyproject.toml
- Export step —
scripts/export_notebooks.pyrunsmarimo export htmlon each notebook, writing static HTML toapp/public/notebooks/ - Next.js app (
localhost:3000) — navigation shell that serves the exported HTML viaMarimoIframe - CI — the deploy workflow exports notebooks and builds the site on push to
main. A weekly refresh re-exports to pick up fresh data.
Each page in the Next.js app is a thin wrapper around a MarimoIframe component:
<MarimoIframenotebookName="notebooks/insights/developer-lifecycle"/>- Create
notebooks/<category>/<name>.pyusing the standard template below - Add a page at
app/app/<category>/<name>/page.tsx - Add a nav entry to
app/components/Sidebar.tsx - Run
cd app && pnpm export:notebooksto generate the HTML
importmarimo__generated_with="unknown"app=marimo.App(width="full")
@app.cell(hide_code=True)defsetup_pyoso():
# This code sets up pyoso to be used as a database provider for this notebook# This code is autogenerated. Modification could lead to unexpected results :)importpyosoimportmarimoasmopyoso_db_conn=pyoso.Client().dbapi_connection()
returnmo, pyoso_db_conn# Add cells hereif__name__=="__main__":
app.run()For detailed notebook conventions, see notebooks/claude.md.
| Variable | Description |
|---|---|
OSO_API_KEY | Required. OSO data warehouse access key. |