Local development setup#

This page gives a repeatable, low-friction way to run the Cellucid web app locally for debugging and development.

Because the app is shipped as native ES modules (no bundler required), the setup is usually just “run a static server and reload”.

At a glance#

Audience

  • Wet lab / non-technical: you can use this to reproduce bugs and capture screenshots, without writing code.

  • Computational users: use this to run on the same machine as cellucid-python server mode.

  • Developers: use this for rapid iteration; then read Debugging playbook.

Time

  • 2–5 minutes for “hello world” local run

  • 10–20 minutes if you also want to test remote server + Jupyter workflows

Prerequisites

  • A current stable Chrome, Edge, Firefox, or Safari release with WebGL2

  • Python 3 (for a simple local static server), or any equivalent local server


Step 0: Know the two “local” modes#

There are two distinct local workflows:

  1. Local web app: you run the frontend from this workspace (cellucid/), and you load demo or local files.

  2. Local data server: you run cellucid-python to serve a dataset, and the frontend connects to it (either from your local web app or from https://www.cellucid.com).

They are often used together, but debugging is faster when you can clearly say which one you’re using.


Step 1: Run the Cellucid web app locally#

From the workspace root:

cd cellucid
python -m http.server 8000

Then open:

  • http://localhost:8000

Important

Do not open cellucid/index.html via file://. Browsers will block ES module imports and cross-origin fetches in ways that look like “random failures”. Always use an HTTP server.



Step 3: Load a dataset (choose one)#

Option A: Use built-in demo datasets (fastest)#

If the app can fetch datasets.json from the configured sample catalog, the dataset dropdown will populate from the local-demo source.

Configure the sample catalog via:

  • <meta name="cellucid-sample-catalog" ...> in cellucid/index.html, or

  • ?sampleCatalog=... as a runtime override (useful in development): one absolute folder URL ending in / that holds a datasets.json.

This is best for:

  • UI work

  • rendering/LOD work

  • session/export work

Option B: Use the browser file picker (local-user)#

Use Open… under Open data → File or folder to select:

  • a file (File…): .h5ad, .h5mu, .loom, a 10x Cell Ranger .h5, an R object (.rds, .rda/.RData, gzipped or not), or a .zarr.zip archive holding one AnnData or MuData Zarr store, or

  • a folder (Folder…): a .zarr store (AnnData or MuData), a Cell Ranger outs/ folder, or a MatrixMarket folder

or drop one of them anywhere on the page. The formats are the entries of data/input-formats.js.

This is best for:

  • “real user” workflows with no Python server running

  • testing permission/UX issues around file pickers

Option C: Connect to a local Python server (cellucid serve)#

Run (in another terminal) from your cellucid-python environment:

cellucid serve /path/to/dataset.h5ad --dataset-name "My dataset" --dataset-id my-dataset
# or
cellucid serve /path/to/dataset.zarr --dataset-name "My dataset" --dataset-id my-dataset

Then in the Cellucid UI, type the server’s address into the Link or server bar under Open data and click Open:

  • 127.0.0.1:<port>, http://127.0.0.1:<port>, or just <port>

This is best for:

  • debugging the served-AnnData path (data/remote-source.js, data/served-anndata.js): the browser reads the store in place with range requests, and the server only serves its bytes

  • Zarr store folders, which the server serves key by key

  • any other format of the registry (.h5mu, .loom, 10x, MatrixMarket, R objects): the server serves the bytes and the browser reads them

  • reproducible debugging (server logs + client logs)

Note

If you are using the hosted app (https://www.cellucid.com) and a local server, you are doing an https → http connection. Most modern browsers allow https://… pages to talk to http://localhost / http://127.0.0.1, but if your environment blocks it, run the web app locally (http://localhost:8000) and connect to the server from there.

Option D: Notebook viewer (hooks + events)#

If you are developing the Python↔frontend hooks system:



Troubleshooting#

Symptom: “Blank page / canvas is black”#

First, check whether you got a full-screen startup failure card. If you did, the bootstrap failed deliberately: the heading names the kind of problem and Details holds the exact reason — read it before anything else. A truly blank page means the module graph never ran at all, which is a serving problem, not an application one.

Likely causes (ordered):

  1. WebGL2 not available (browser/GPU issue) — you will get the card headed “This browser cannot run Cellucid”, with “WebGL2 is required but not supported in this browser.” under Details.

  2. A JS exception during startup prevented viewer initialization.

  3. The app cannot fetch required files due to server/CORS/missing paths.

How to confirm:

  • DevTools → Console: look for the first error after “Starting…”.

  • DevTools → Network: reload and look for 404 or blocked requests.

Symptom: “The data-source buttons are disabled”#

That is the intended initial state. Controls whose listeners are wired after an await in the bootstrap are authored disabled and enabled only once they are live; the line under the Open data heading (#data-source-status) says which phase you are in. If they never enable, the bootstrap threw — look for the startup card or the console.

Locally this window is short enough to miss; throttle the network in DevTools if you need to observe it.

Fix:

  • Confirm the current browser exposes WebGL2 with document.createElement("canvas").getContext("webgl2") !== null.

  • Ensure you are serving from the cellucid/ directory.

  • Enable debug logs and reload (Step 2).

Symptom: “Module script failed to load”#

Likely causes:

  • You opened via file://, or the server is sending incorrect MIME types for .js.

Fix:

  • Use python -m http.server from cellucid/ (Step 1).

Symptom: “Remote server connect fails / CORS error”#

Likely causes:

  • The server is not running.

  • The server does not send CORS headers for the Cellucid origin you’re using.

  • Corporate proxy/ad blocker interferes with localhost requests.

How to confirm:

  • Open the remote server URL in a new tab and see if it responds.

  • Check DevTools → Network for failed fetch requests and CORS messages.

Fix:

  • Use the locally hosted app (http://localhost:8000) and connect from there.

  • Or configure the server origin/CORS (Python side).


Next: Build, run, and deployment.