# clusterProfiler: one interface for gene set enrichment across many organisms

> clusterProfiler is a Bioconductor R package that runs over-representation analysis, GSEA and topology-aware enrichment through a shared enrichit engine, and it presents the results as tidy data frames rather than a pile of separate result objects.

**YuLab-SMU/clusterProfiler** — :bar_chart: A universal enrichment tool for interpreting omics data

- Repository: https://github.com/YuLab-SMU/clusterProfiler
- Website: https://yulab-smu.top/biomedical-knowledge-mining-book/
- Stars: 1,248 · Forks: 269
- Language: R
- License: not declared
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/yulab-smu-clusterprofiler

## What the package is for, in the author's words

clusterProfiler supports exploring functional characteristics of both coding and non-coding genomics data for thousands of species with up-to-date gene annotation. It is a Bioconductor package, and the release badge points at version 4.20.0 on the Bioconductor release while the development version is 4.21.2.

Three of the stated goals stand out.

It provides a universal interface for gene functional annotation from a variety of sources, and so can be applied in diverse scenarios. It provides a tidy interface to access, manipulate and visualize enrichment results, which is the part that matters most in practice, because an enrichment analysis is only as useful as what you can do with the table afterwards. Datasets obtained from multiple treatments and time points can be analyzed and compared in a single run, which easily reveals functional consensus and differences among distinct conditions.

That third point is what separates a modern enrichment package from the older ones. Comparing a treated group against a control and a dose group against a control, in one call, with the comparison built in, is the feature that saves the most time in a differential expression workflow.

Underneath, it uses enrichit as the underlying engine for ORA, GSEA and topology-aware enrichment analysis, while providing a high-level and user-friendly interface for biological interpretation. So the algorithm is a separate component and the R package is the interface layer, which is the right split for something that has to track annotation changes over time.

The project is maintained by Guangchuang Yu at the School of Basic Medical Sciences, Southern Medical University, and the documentation points at the contribution knowledge mining pages and the biomedical knowledge mining book. The last push was on 2026-10-08, and there are no published GitHub releases because the distribution channel is Bioconductor.

## Installing from Bioconductor, or from the development branch

The install is two paths, and the released one is the sensible default.

The released version comes from Bioconductor:

```r
if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("clusterProfiler")
```

And the development version comes from GitHub:

```r
if (!requireNamespace("remotes", quietly = TRUE))
    install.packages("remotes")
remotes::install_github("YuLab-SMU/clusterProfiler")
```

The pattern in both is the same and it is the standard Bioconductor idiom. The helper package is checked with requireNamespace and quietly set to TRUE, and only installed if it is missing, so the script is safe to re-run in a session that already has it.

The distinction between the two paths is not just about stability. Bioconductor releases are tied to a specific R and BioC version, so the release channel is what guarantees that the annotation data and the package agree. Installing from GitHub gives you the development branch, where the package and the data may be out of step, and that matters more here than for most packages because the whole value is in the correspondence between the analysis code and the annotation.

The default branch in the repository is devel, not master, and the Makefile confirms that: the update target fetches all remotes, checks out devel, and merges both upstream and origin into it. The release branch is a separate one, named after the Bioconductor release, which the Makefile refers to as RELEASE_3_23, and there is a target that deletes that branch.

So the repository is structured for a two-track release: a moving devel branch and a frozen branch per Bioconductor release. The version badges show the same thing, with 4.20.0 as the release and 4.21.2 as the development version.

## The Makefile, and what the data targets actually do

The Makefile is a package-development Makefile, and its targets explain a lot about how the package is maintained.

The package name and version are read out of the DESCRIPTION file with sed rather than being written in the Makefile, so there is a single source of truth. The default target is all, which runs rd, check and clean in sequence.

The documentation targets are the interesting part. The rd target runs devtools::document() to regenerate the help pages from the R sources, and the readme target renders README.Rmd to Markdown with rmarkdown, sourcing a set_proxy() helper first, which is the piece that makes the render work behind a network proxy. The readme is generated rather than written, so the README you read on the package page is built from README.Rmd in the repository.

There is a data target called updatedata, and it does two things. It sources the package's own extdata/kegg_pathway_category.r, and then it calls clusterProfiler:::get_kegg_species(save=TRUE), which is the function that pulls the KEGG species list and saves it as a data object in the package. The prerelease target does the same call but from inside the data directory.

That detail is worth pausing on. KEGG species information is fetched and baked into the package, which means the package carries a snapshot of which organisms KEGG covers, and that snapshot is refreshed by a target that needs network access. The local_test target test_interpret runs the local test script directly with Rscript rather than through the test framework.

For building and checking, the targets use devtools::build(), devtools::check() and devtools::install() for the fast loop, with build2 and check2 doing the same with R CMD build and R CMD check against the tarball, which is what Bioconductor requires. There is a separate bioccheck target for BiocCheck, and the release and biocinit targets set up the git remote at git.bioconductor.org for the package, then check out the release branch and fetch everything.

## The package layout, and the vignettes

The repository is a standard R package with the usual directories, plus a few that say something about the project.

The R/ directory holds the package code, man/ holds the generated help pages, tests/ holds the test suite, vignettes/ holds the long-form documentation, and inst/ holds installed assets, including the extdata with the KEGG pathway category data. data/ holds the packaged datasets, and there is a local_test/ directory for scripts run outside the test framework. NEWS and NEWS.md are the changelogs, and DESCRIPTION, NAMESPACE and the R build files are the package metadata.

The vignettes directory is the part that makes this package usable by someone who is not already an R bioinformatics developer, because a vignette is a document that is built, run and shipped with the package, so the examples in it are known to execute against the version you installed.

The Makefile also has a target called updatedata that we have already seen, and a tests directory whose presence alongside local_test tells you the project distinguishes between the checked test suite and one-off diagnostic scripts. The test_interpret target runs local_test/test_interpret.R directly with Rscript, which is how you check a single interpretation path without running everything.

Other top level entries include a Makefile that also references the upstream remote for merges, an outdated/ directory, a CONTEXT.md, a CONTRIBUTING.md, a .Rbuildignore for excluding files from the built tarball, and a graphic-abstract image from The Innovation used in the README.

The default branch is devel, and the repository is not archived, so the code is current even though the published versions move on Bioconductor's schedule rather than on a release-by-release cadence most users would recognise.

## Conclusion

clusterProfiler suits a computational biologist who needs enrichment results for a list of genes across several organisms, or who wants to compare conditions in one run, and it suits a reader who wants the enrichment results as data frames they can post-process in R. It is a poor fit for a pipeline that cannot reach the KEGG and other annotation sources at run time, because the package relies on up-to-date gene annotation and on external resources, and it is a poor fit for a project that needs a stable API, since the release line is on Bioconductor's schedule rather than your own. Before adopting, install the released version from Bioconductor rather than the development branch, and check which annotation sources your organism needs are available in the version you install.

## FAQ

### What is the clusterProfiler R package?

It is a Bioconductor package for exploring the functional characteristics of coding and non-coding genomics data across thousands of species, using up-to-date gene annotation. It uses enrichit as the underlying engine for ORA, GSEA and topology-aware enrichment, and exposes the results through a tidy interface.

### How do I install clusterProfiler?

From Bioconductor with BiocManager::install("clusterProfiler"), installing BiocManager first if it is missing, or the development version with remotes::install_github("YuLab-SMU/clusterProfiler"). The released Bioconductor version is 4.20.0 and the development version is 4.21.2.

### Why does the clusterProfiler Makefile fetch KEGG species data?

The updatedata and prerelease targets call clusterProfiler:::get_kegg_species(save=TRUE) to pull the KEGG species list and save it into the package's data directory, and a related script sources the packaged extdata/kegg_pathway_category.r. That means the organism coverage shipped with the package is a snapshot that a maintainer refreshes, and running the package's own update target is how that snapshot changes.

### How does the clusterProfiler repository handle releases?

The default branch is devel, which the update target fetches and merges from both upstream and origin. A separate branch per Bioconductor release, referred to in the Makefile as RELEASE_3_23, holds the frozen source for that release, and the release target checks it out and fetches everything. The build and check targets exist in a devtools variant and an R CMD variant, and there is a separate BiocCheck target.

## Sources

- [Issues](https://github.com/YuLab-SMU/clusterProfiler/issues)
- [Project website](https://yulab-smu.top/biomedical-knowledge-mining-book/)
- [README](https://github.com/YuLab-SMU/clusterProfiler/blob/devel/README.md)
- [YuLab-SMU/clusterProfiler on GitHub](https://github.com/YuLab-SMU/clusterProfiler)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yulab-smu-clusterprofiler
