Thank you for your interest in contributing to Celldega! π§¬
- Python 3.10+ β Download here
- Node.js 16+ β Download here
- npm 8+ β Install guide
- Git β Download here
# Clone Celldega repo
git clone https://github.com/broadinstitute/celldega.git
cd celldega
# Setup everything: Python venv, install dependencies, pre-commit hooks
bash ./scripts/setup.shThat's it! Your development environment is ready. π
source dega/bin/activate # Activate environment
npm run dev # Start development server- Write clear, descriptive code
- Add tests for new features
- Test in Jupyter:
jupyter lab examples/
bash ./scripts/test.sh # Run all tests
git commit -m "feat: your amazing feature"That's the entire workflow! Our automation handles formatting, linting, and quality checks.
Understanding the project's tooling helps you contribute more effectively. Here's what's configured where:
| File/Directory | Purpose | Tools Configured |
|---|---|---|
| π CI/CD & Automation | ||
.github/workflows/ci.yml |
Continuous Integration | pytest, Jest, ESLint, Prettier, Ruff, Safety, Bandit |
.github/dependabot.yml |
Dependency updates | Automated Python, npm, and GitHub Actions updates |
.pre-commit-config.yaml |
Git hooks | Ruff (Python), Prettier, ESLint, basic file checks |
| π Python Configuration | ||
pyproject.toml |
Python package config | pytest, Ruff (linting + formatting), build system |
| π JavaScript Configuration | ||
package.json |
JavaScript dependencies | Jest (testing), ESLint (linting), Prettier (formatting) |
eslint.config.js |
JavaScript linting rules | ESLint with import ordering, code quality rules |
jest.setup.js |
Test environment setup | Jest with jsdom, testing-library |
| π» Development Scripts | ||
scripts/setup.sh |
Environment setup | Python venv, npm install, pre-commit hooks |
scripts/test.sh |
Test runner | pytest, Jest, linting checks |
scripts/utils.sh |
Shared utilities | Helper functions for scripts |
| π·π» Build & Bundling | ||
build.js |
JavaScript bundling | esbuild with WASM support |
On Every Commit (Pre-commit Hooks):
- β Ruff formats and lints Python code
- β Prettier formats JavaScript/JSON/YAML
- β ESLint checks JavaScript code quality
- β Basic file checks (trailing whitespace, merge conflicts)
On Every Push/PR (CI Pipeline):
- π§ͺ Testing: pytest (Python), Jest (JavaScript)
- π Code Quality: Ruff, ESLint, Prettier checks
- π Security: Safety (Python deps), Bandit (code analysis)
- π¦ Build: Package building and installation tests
- π Release: Automated PyPI publishing on tags
bash ./scripts/test.sh # Run everything
bash ./scripts/test.sh python # Python tests only
bash ./scripts/test.sh js # JavaScript tests only
bash ./scripts/test.sh coverage # Generate coverage reportπ Python (pytest) - Add tests like this:
# tests/unit/test_my_feature.py
from celldega.utils import my_function
def test_my_function():
result = my_function('input')
assert result == 'expected'π JavaScript (Jest) - Add tests like this:
// js/__tests__/myFeature.test.js
import { myFunction } from '../utils/myFeature.js';
test('should handle basic case', () => {
expect(myFunction('input')).toBe('expected');
});The example notebooks under docs/examples/ render their interactive widgets
(Landscape, Clustergram, β¦) statically in the built docs by embedding the
widget state into the notebook. mkdocs-jupyter renders that saved state β it
does not execute notebooks at build time β so the state must be present in
the committed .ipynb.
Render a notebook with embedded widget state using nbconvert:
# In place β re-executes the notebook and embeds widget state
CELLDEGA_ESM_VERSION=<released-version> jupyter nbconvert \
--to notebook --execute --inplace \
--ExecutePreprocessor.timeout=900 \
--ExecutePreprocessor.iopub_timeout=120 \
docs/examples/brief_notebooks/YourNotebook.ipynb
# Standalone HTML export (writes YourNotebook.html next to it)
CELLDEGA_ESM_VERSION=<released-version> jupyter nbconvert --to html --execute \
--ExecutePreprocessor.timeout=900 \
--ExecutePreprocessor.iopub_timeout=120 \
docs/examples/brief_notebooks/YourNotebook.ipynbTwo flags/vars matter:
CELLDEGA_ESM_VERSION=<released-version>(e.g.0.17.0) β makes each widget loadcelldega.jsfrom jsdelivr via a tiny_esmshim instead of inlining the ~10 MB bundle once per widget. The pinned version must be published to npm. Without it (or withCELLDEGA_LOCAL_ESM=1) the local bundle is inlined: self-contained and offline-capable, but ~10 MB per widget. For local JS development (npm run dev/HMR), setCELLDEGA_LOCAL_ESM=1so the widget uses your workingcelldega.jsrather than the CDN.--ExecutePreprocessor.iopub_timeout=120β theLandscapeemits large (10 MB+) messages; the default 4 s timeout drops them, leaving blank widgets. (store_widget_stateis alreadyTrueby default, so widget state is embedded automatically.)
Notes:
-
nbconvert runs the kernel in the notebook's own directory, so a notebook with a repo-root-relative data path will resolve it relative to that directory.
-
Sanity-check that the bundle wasn't inlined (shim β 105 bytes, inlined β 10 MB):
python -c "import json,sys; s=json.load(open(sys.argv[1]))['metadata'].get('widgets',{}).get('application/vnd.jupyter.widget-state+json',{}).get('state',{}); print('max _esm bytes:', max((len(json.dumps(m['state']['_esm'])) for m in s.values() if '_esm' in m.get('state',{})), default=0))" \ docs/examples/brief_notebooks/YourNotebook.ipynb -
These notebooks are matched by the
*.ipynbrule in.gitignore, so commit a new one explicitly withgit add -f docs/examples/.../YourNotebook.ipynb.
No need to worry about formatting! Our pre-commit hooks automatically:
- β Format Python code with Ruff
- β Format JavaScript code with Prettier
- β Fix linting issues
- β Check for common mistakes
- Python:
snake_casefunctions,PascalCaseclasses - JavaScript:
camelCasefunctions,PascalCaseclasses - Files:
my_module.py,myComponent.js - Type Annotations: Always add proper typing for better code clarity and IDE support
Python Typing Examples
from typing import List, Optional, Dict, Any
import pandas as pd
def process_cell_data(
cells: pd.DataFrame,
cluster_labels: Optional[List[int]] = None,
metadata: Dict[str, Any] = {}
) -> pd.DataFrame:
"""Process cell data with optional clustering information."""
# Implementation here
return processed_cellsJavaScript JSDoc Examples
/**
* Render cells on deck.gl layer with interactive selection
* @param {Array<{x: number, y: number, cluster: number}>} cellData - Array of cell coordinates
* @param {Object} options - Rendering options
* @param {string} options.colorBy - Property to color cells by
* @param {boolean} options.interactive - Enable cell selection
* @returns {Promise<DeckGLLayer>} Configured deck.gl layer
*/
async function renderCellLayer(cellData, options = {}) {
// Implementation here
return layer;
}TypeScript Examples
interface CellData {
x: number;
y: number;
cluster: number;
[key: string]: any;
}
interface RenderOptions {
colorBy?: string;
interactive?: boolean;
opacity?: number;
}
async function renderCellLayer(
cellData: CellData[],
options: RenderOptions = {}
): Promise<DeckGLLayer> {
// Implementation here
return layer;
}Use these prefixes:
# STRUCTURE: "activity(module): ..."
git commit -m "feat(deck-gl): implement interactive cell selection widget" # New Feature
git commit -m "optim(deck-gl): optimize WebGL shader compilation for speed" # Optimization
git commit -m "fix(deck-gl): resolve memory leak in large dataset rendering" # Bug fix
git commit -m "hotfix(deck-gl): π΄ resolve data loading issue" # Hot bug fix (needs urgent rework -> create GitHub/Jira issue)
git commit -m "docs(deck-gl): add WebGL troubleshooting guide for users" # Documentation
git commit -m "test(deck-gl): add integration tests for widget lifecycle" # tests
git commit -m "infra(jest): configure coverage reporting for CI pipeline" # Infrastructure
Found a bug? Use our issue templates:
- π Bug Report: Include your environment and steps to reproduce
- π Feature Request: Describe what you'd like to see
- π Documentation: Suggest improvements to docs or examples
- 𧬠Add example datasets from your research
- π Create tutorial notebooks
- π Improve documentation with domain expertise
- π§ͺ Test with real-world data and report issues
- β‘ Optimize performance for large datasets
- π¨ Improve visualization components
- π§ Add new analysis algorithms
- π Enhance web integration
- π Fix typos and improve clarity
- π§ͺ Add tests for edge cases
- π― Improve user experience
- π€ Help others in discussions
Stuck? Here's how to get unstuck:
./scripts/setup.sh --status # Check what's wrong
./scripts/setup.sh --reset # Nuclear option - fresh start
./scripts/setup.sh --verbose # See detailed outputCommon Issues
"Permission denied"
chmod +x scripts/*.sh"Python/Node.js/npm not found"
- Install from links above
- Check versions:
python --version,node --version,npm --version
"npm: command not found"
# npm comes with Node.js - install Node.js from nodejs.org
# or update Node.js to get latest npm"Import errors"
./scripts/setup.sh # Reinstall dependencies"Tests failing"
bash ./scripts/test.sh --verbose # See detailed error messages"node_modules missing"
npm install # Reinstall JavaScript dependencies- π¬ GitHub Discussions - Ask questions
- π GitHub Issues - Report bugs
- π§ Contact maintainers directly
Click for advanced setup options
bash ./scripts/setup.sh --env-name my-celldega-envnpm run dev # Standard development
npm run dev:watch # Watch mode with hot reload
npm run build # Production build
npm run serve # Serve production buildpytest tests/unit/ # Specific test directory
pytest -k "test_clustering" # Tests matching pattern
pytest --cov-report=html # HTML coverage report
npm run test:js:watch # JavaScript tests in watch modenpm install # Install all dependencies
npm ci # Install from lockfile (CI)
npm run test:js # Run JavaScript tests
npm run lint:js # Lint JavaScript code
npm run format:js # Format JavaScript code
npm outdated # Check for outdated packages
npm update # Update dependenciesInstall these extensions for the best experience:
- Python - Core Python support
- Ruff - Python linting and formatting
- ESLint - JavaScript linting
- Prettier - Code formatting
- Jupyter - Notebook support
Contributors are celebrated in:
- π
CONTRIBUTORS.mdfile - π GitHub contributors graph
- π° Release notes for significant contributions
- π Special mentions in community updates
- Start small - Fix documentation or add a simple test first
- Ask early - Use Discussions to validate ideas before coding
- Test thoroughly - Include edge cases and error conditions
- Document changes - Help future contributors understand your work
- Be patient - We review all contributions carefully
- Use npm efficiently - It comes with Node.js and handles all dependencies well!
We're building something amazing together! Please be:
- π€ Respectful - Everyone was new once
- π Inclusive - Welcome diverse perspectives
- ποΈ Constructive - Focus on solutions
- π Educational - Help others learn
Ready to contribute? Fork the repo and dive in! We can't wait to see what you build. π
Need help? Don't hesitate to reach out - we're here to help you succeed!