--- a
+++ b/docs/contributing.md
@@ -0,0 +1,202 @@
+# Contributing guide
+
+Scanpy provides extensive [developer documentation][scanpy developer guide], most of which applies to this repo, too.
+This document will not reproduce the entire content from there.
+Instead, it aims at summarizing the most important information to get you started on contributing.
+
+We assume that you are already familiar with git and with making pull requests on GitHub.
+If not, please refer to the [scanpy developer guide][].
+
+## Cloning the repository
+
+ehrapy consists of this main repository and a git submodule [ehrapy-tutorials](https://github.com/theislab/ehrapy-tutorials) which hosts tutorial notebooks.
+Clone both using:
+
+```bash
+git clone --recurse-submodules https://github.com/theislab/ehrapy
+```
+
+More details on the tutorials submodule are described in the [Writing documentation](#writing-documentation) section.
+
+## Installing dev dependencies
+
+In addition to the packages needed to _use_ this package, you need additional python packages to _run tests_ and _build
+the documentation_. It's easy to install them using `pip`:
+
+```bash
+cd ehrapy
+pip install -e ".[dev,test,docs]"
+```
+
+## Code-style
+
+This project uses [pre-commit][] to enforce consistent code-styles. On every commit, pre-commit checks will either
+automatically fix issues with the code, or raise an error message.
+
+To enable pre-commit locally, simply run
+
+```bash
+pre-commit install
+```
+
+in the root of the repository. Pre-commit will automatically download all dependencies when it is run for the first time.
+
+Alternatively, you can rely on the [pre-commit.ci][] service enabled on GitHub. If you didn't run `pre-commit` before
+pushing changes to GitHub it will automatically commit fixes to your pull request, or show an error message.
+
+If pre-commit.ci added a commit on a branch you still have been working on locally, simply use
+
+```bash
+git pull --rebase
+```
+
+to integrate the changes into yours.
+While the [pre-commit.ci][] is useful, we strongly encourage installing and running pre-commit locally first to understand its usage.
+
+Finally, most editors have an _autoformat on save_ feature. Consider enabling this option for [black][black-editors]
+and [prettier][prettier-editors].
+
+[black-editors]: https://black.readthedocs.io/en/stable/integrations/editors.html
+[prettier-editors]: https://prettier.io/docs/en/editors.html
+
+## Writing tests
+
+```{note}
+Remember to first install the package with `pip install -e ".[dev,test,docs]"`
+```
+
+This package uses the [pytest][] for automated testing. Please [write tests][scanpy-test-docs] for every function added
+to the package.
+
+Most IDEs integrate with pytest and provide a GUI to run tests. Alternatively, you can run all tests from the
+command line by executing
+
+```bash
+pytest
+```
+
+in the root of the repository. Continuous integration will automatically run the tests on all pull requests.
+
+[scanpy-test-docs]: https://scanpy.readthedocs.io/en/latest/dev/testing.html#writing-tests
+
+## Publishing a release
+
+### Updating the version number
+
+Before making a release, you need to update the version number. Please adhere to [Semantic Versioning][semver], in brief
+
+> Given a version number MAJOR.MINOR.PATCH, increment the:
+>
+> 1.  MAJOR version when you make incompatible API changes,
+> 2.  MINOR version when you add functionality in a backwards compatible manner, and
+> 3.  PATCH version when you make backwards compatible bug fixes.
+>
+> Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
+
+Once you are done, run
+
+```
+git push --tags
+```
+
+to publish the created tag on GitHub.
+
+### Building and publishing the package on PyPI
+
+Python packages are not distributed as source code, but as _distributions_. The most common distribution format is the so-called _wheel_. To build a _wheel_, run
+
+```bash
+python -m build
+```
+
+This command creates a _source archive_ and a _wheel_, which are required for publishing your package to [PyPI][]. These files are created directly in the root of the repository.
+
+Before uploading them to [PyPI][] you can check that your _distribution_ is valid by running:
+
+```bash
+twine check dist/*
+```
+
+and finally publishing it with:
+
+```bash
+twine upload dist/*
+```
+
+Provide your username and password when requested and then go check out your package on [PyPI][]!
+
+For more information, follow the [Python packaging tutorial][].
+
+It is possible to automate this with GitHub actions, see also [this feature request][pypi-feature-request]
+in the cookiecutter-scverse template.
+
+[python packaging tutorial]: https://packaging.python.org/en/latest/tutorials/packaging-projects/#generating-distribution-archives
+[pypi-feature-request]: https://github.com/scverse/cookiecutter-scverse/issues/88
+
+## Writing documentation
+
+Please write documentation for new or changed features and use-cases. This project uses [sphinx][] with the following features:
+
+- the [myst][] extension allows to write documentation in markdown/Markedly Structured Text
+- Google-style docstrings
+- Jupyter notebooks as tutorials through [myst-nb][] (See [Tutorials with myst-nb](#tutorials-with-myst-nb-and-jupyter-notebooks))
+- [Sphinx autodoc typehints][], to automatically reference annotated input and output types
+- Citations (like {cite:p}`Virshup_2023`) can be included with [sphinxcontrib-bibtex](https://sphinxcontrib-bibtex.readthedocs.io/)
+
+See the [scanpy developer docs](https://scanpy.readthedocs.io/en/latest/dev/documentation.html) for more information
+on how to write documentation.
+
+### Tutorials with myst-nb and jupyter notebooks
+
+The documentation is set-up to render jupyter notebooks stored in the `docs/tutorials` directory using [myst-nb][].
+Currently, only notebooks in `.ipynb` format are supported that will be included with both their input and output cells.
+
+These notebooks come from [ehrapy-tutorials](https://github.com/theislab/ehrapy-tutorials) which is a git submodule of ehrapy.
+
+#### Working with the git submodule
+
+Whenever the tutorials are updated in the submodule, two pull requests need to be made.
+Submit a pull request to [ehrapy-tutorials](https://github.com/theislab/ehrapy-tutorials) and ensure that the CI passes.
+Further, submit a pull request on the ehrapy repository where the submodule also contains the commit and ensure that
+the documentation as build by ReadTheDocs properly shows the updated notebooks.
+Both pull requests need to be merged to ensure that no repository gets out of sync.
+
+### Hints
+
+- If you refer to objects from other packages, please add an entry to `intersphinx_mapping` in `docs/conf.py`. Only
+  if you do so can sphinx automatically create a link to the external documentation.
+- If building the documentation fails because of a missing link that is outside your control, you can add an entry to
+  the `nitpick_ignore` list in `docs/conf.py`
+
+### Building the docs locally
+
+```bash
+cd docs
+make html
+open _build/html/index.html
+```
+
+<!-- Links -->
+
+[scanpy developer guide]: https://scanpy.readthedocs.io/en/latest/dev/index.html
+[cookiecutter-scverse-instance]: https://cookiecutter-scverse-instance.readthedocs.io/en/latest/template_usage.html
+[github quickstart guide]: https://docs.github.com/en/get-started/quickstart/create-a-repo?tool=webui
+[codecov]: https://about.codecov.io/sign-up/
+[codecov docs]: https://docs.codecov.com/docs
+[codecov bot]: https://docs.codecov.com/docs/team-bot
+[codecov app]: https://github.com/apps/codecov
+[pre-commit.ci]: https://pre-commit.ci/
+[readthedocs.org]: https://readthedocs.org/
+[myst-nb]: https://myst-nb.readthedocs.io/en/latest/
+[jupytext]: https://jupytext.readthedocs.io/en/latest/
+[pre-commit]: https://pre-commit.com/
+[anndata]: https://github.com/scverse/anndata
+[mudata]: https://github.com/scverse/mudata
+[pytest]: https://docs.pytest.org/
+[semver]: https://semver.org/
+[sphinx]: https://www.sphinx-doc.org/en/master/
+[myst]: https://myst-parser.readthedocs.io/en/latest/intro.html
+[numpydoc-napoleon]: https://www.sphinx-doc.org/en/master/usage/extensions/napoleon.html
+[numpydoc]: https://numpydoc.readthedocs.io/en/latest/format.html
+[sphinx autodoc typehints]: https://github.com/tox-dev/sphinx-autodoc-typehints
+[pypi]: https://pypi.org/