# Carrot2 and the mechanics of automatic document clustering

> Carrot2 is a Java library that groups related documents and labels each group with short key terms, and it ships with an HTTP/JSON clustering server for Solr and Elasticsearch. The code tells you more about what it does than the README does.

**carrot2/carrot2** — Carrot2: Text Clustering Algorithms and Applications

- Repository: https://github.com/carrot2/carrot2
- Website: http://www.carrot2.org
- Stars: 859 · Forks: 222
- Language: Java
- License: not declared
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/carrot2-carrot2

## Carrot2 clusters documents, it does not search for them

Carrot2 describes itself as a programming library for clustering text, and the distinction matters when you evaluate it. The library does not retrieve anything. It takes a set of documents you have already collected and discovers groups of related documents inside that set, then labels each group with short key terms or phrases. The README uses search result titles and snippets as the example input, turning a page of search hits into visible clusters with a label attached to each one.

That framing puts Carrot2 in a specific place. It is not a crawler, an index, or a relevance engine. It sits after retrieval, or alongside retrieval engines that already know how to fetch and rank. The people it serves are engineers who own a search stack and find that a ranked list of similar-looking results is hard to read, and who want the results folded into named topics instead. The people it does not serve are someone starting from nothing who wants search out of the box, or someone who wants to write their own clustering logic from first principles.

The input is also modest in size. The unit of work is a document with a title and a snippet or body, and the output is a partition of those documents plus a label for each part. Whether that partition is useful depends on the retrieval step feeding it, which is why the README frames the tool around integration rather than around a standalone command.

## Two delivery shapes: a library dependency and the DCS

Carrot2 ships in two shapes, and the choice between them determines how much of your codebase touches it. The first is the library itself. The README states that Carrot2 is a software component that typically integrates with other software as a library dependency, and it points at the API documentation available with each release for the details. The repository layout backs this up: the top level carries core/, lang/, core-examples/ and infra/ alongside the build files, which reads like a multi-module Java project with a language abstraction layer and a separate module for usage examples rather than a single application jar.

The second shape is the DCS, the document clustering server. Binary releases published on GitHub ship with a HTTP/JSON REST API service called the DCS, described in the README as existing for integration with other languages. That is the practical escape hatch for teams whose application stack is not Java: a Java process exposing JSON over HTTP, callable from anything that can make an HTTP request.

So the architectural question for a new user is whether the clustering runs inside your application or beside it. The library path keeps everything in one process and lets you tune it in code. The DCS path keeps the clustering service separate and makes the boundary an API contract, which is simpler to operate across language lines but adds a network hop and a service to deploy.

## Building the distribution yourself with the Gradle wrapper

The README gives one build command for people who need the distribution built from sources rather than pulled from a release. It uses the checked in Gradle wrapper, and the distribution target is named distribution, which matches the distribution/ directory at the repository root:

```bash
./gradlew -p distribution assemble
```

After a successful run the README says the distribution is placed under distribution/build/dist/, and a compressed version appears at distribution/build/distZip/. Two output locations for one build is worth noting: the unpacked tree is what you would run the DCS from, and the archive is what you would hand to a deployment pipeline. The repository also contains distribution-tests/, which suggests the build is checked beyond a simple compile, and the top level includes build-options.properties, gradle.properties and versions.lock, so dependency versions appear to be pinned rather than floating.

The practical note is that the source path has real prerequisites that the README does not spell out. It does not state a minimum Java version, it does not say whether the wrapper needs a matching Gradle distribution downloaded at run time, and it does not describe what a failing build looks like. Anyone building from source should plan to read gradle.properties and build-options.properties directly and expect to satisfy the Java requirement from the build files rather than from the documentation.

## Starting the DCS and reading its bundled docs

The README gives a short start sequence for the binary release path, and it is worth following exactly because the documentation it serves is bundled rather than hosted for the running instance. Once the release archive is downloaded and unpacked, the DCS starts from its own directory:

```shell script
cd dcs
./dcs
```

Two URLs matter after that. The documentation for the running service is at localhost:8080/doc/, and the JavaDoc API reference is at localhost:8080/javadoc/. Seeing both in the README makes one design point clear: the DCS is not just an endpoint, it is a self-describing service that carries its own developer documentation. That is the practical reason to prefer a binary release for evaluation, since the same archive gives you a runnable server and the reference material for calling it.

Note the split with the hosted documentation. The README states that the documentation for the latest release is always at the project's release documentation site, while the developer documentation and examples are described as part of the binary releases. In other words, the version specific API detail lives in the archive you downloaded, and a hosted page can lag behind the commit you are running. Pin the release and read the docs inside it.

The port is fixed at 8080 in the README example, and nothing in the documentation indicates whether that port is configurable. If 8080 is already taken on your host, or if you run more than one instance, that is the first thing you will need to work out yourself.

## Wiring Carrot2 into Solr and Elasticsearch

The README lists two specific integration paths, and both point at existing search servers rather than asking you to write a plugin. The first is an Apache Solr plugin for result clustering, and the second is an Elasticsearch plugin hosted in the carrot2 GitHub organization as elasticsearch-carrot2.

This is the part of the project that most directly answers the who is it for question. Neither plugin requires you to change how documents are indexed or how queries are parsed. A query returns the usual result set, and the clustering step then folds those results into labelled groups. The cost of that arrangement is that the two search stacks already have their own result post-processing stages, and Carrot2 slots into the stage where the ranked list would otherwise be returned flat.

The dependency direction also matters. Carrot2 is the clustering engine, and Solr or Elasticsearch is the retrieval engine, so Carrot2 inherits their operational context. A plugin upgrade or a query change on the search side can change what the clusterer sees, and diagnosing a bad cluster means looking at two systems rather than one. The README does not describe plugin versions, configuration keys, or compatibility matrices, so matching a plugin to a given Carrot2 release is something you have to establish from the plugin's own project rather than from this repository.

## Where Carrot2's own documentation stops

The README is short, and it is short in ways that matter to an adopter. It does not name the clustering algorithms it implements, it does not list the parameters that control cluster count, labelling, or document similarity, and it does not show a request body or a response body for the DCS REST API. It does not state a supported Java version, a minimum heap requirement, or a configuration file format for the server. There is no documented way to upgrade an existing DCS instance in place, and the README does not document rollback at all.

Some of that absence is normal for a library whose reference material is expected to live in the API documentation and in the wiki pages the README points to. But it means you cannot evaluate this project from its README alone. The three layers of information it does reference, the release documentation site, the API documentation inside each binary release, and the project wiki, are where the actual surface area is described, and you should expect to read all three before committing.

The repository structure gives a second read on the same point. Alongside core/ and lang/ there is doc/, which holds the documentation sources, and etc/ plus a distribution-tests/ directory, which indicates that the distribution is tested as a shipped artifact. The project's centre of gravity is the released artifact and the search server plugins. The narrative around it lives in separate places, and a team evaluating it should budget time to pull those together rather than expecting one page to answer the questions.

## Release numbering, the BSD licence, and what it costs to upgrade

Carrot2 is licensed under the BSD license, with the licence text kept in a file named carrot2.LICENSE at the repository root and a separate carrot2.NOTICE file alongside it. The README gives no further detail about the terms, so treat the file itself as the source of truth for what you are licensing, and check the NOTICE file for attribution requirements rather than assuming the BSD summary covers it. Embedding the library in a product that ships to customers is the case where the licence text deserves a read, and where the NOTICE file matters.

On the release side, three tagged releases appear in recent history, all in the 4.8 line: 4.8.4 on 2026-01-12, 4.8.5 on 2026-03-06 and 4.8.6 on 2026-03-08. The last push to the repository was on 2026-10-21, so the code is receiving commits after the most recent tagged build, which is the usual sign of work that has not yet been cut into a release. The repository is not archived.

That combination has a practical consequence for upgrades. Because the patch level moved twice within two days in March 2026, the project is comfortable shipping small fixes quickly, but the version you will find in the newest release is not necessarily the version your plugin is tested against. Pin a specific release, read the API documentation bundled with that archive, and re-run the clustering on a sample of your own result sets after every bump.

## Conclusion

Carrot2 fits teams that already own Solr or Elasticsearch and want labelled result groups rather than a flat relevance list, and it suits Java shops that prefer to depend on a library. It does not suit a reader who needs a standalone search product, a documented set of clustering algorithms, or a clear statement of runtime requirements, since the README leaves those out. Before adopting, check the minimum Java version your build demands, read the API documentation bundled with the release you plan to pin, and confirm that the clustering options exposed there match the output you need.

## FAQ

### How do I install Carrot2?

Carrot2 is a software component that typically integrates with other software as a library dependency, with API documentation shipped with each release. Binary releases are published on GitHub and include the DCS server for integration with other languages.

### How do I run Carrot2 from the command line?

Download a binary release, unpack it, then start the document clustering server from its directory using `cd dcs` followed by `./dcs`. The bundled documentation is then served at localhost:8080/doc/ and the JavaDoc API reference at localhost:8080/javadoc/.

### Can Carrot2 be used with Solr and Elasticsearch?

Yes. The README points to an Apache Solr plugin for result clustering and to an Elasticsearch plugin maintained in the carrot2 GitHub organization. In both cases Carrot2 clusters results returned by the search engine rather than handling retrieval itself.

### What license does Carrot2 use?

The README states that Carrot2 is licensed under the BSD license, with the licence text in a file named carrot2.LICENSE in the repository root. A carrot2.NOTICE file is also present, so check it for attribution requirements before redistributing.

## Sources

- [carrot2/carrot2 on GitHub](https://github.com/carrot2/carrot2)
- [Issues](https://github.com/carrot2/carrot2/issues)
- [Project website](http://www.carrot2.org)
- [README](https://github.com/carrot2/carrot2/blob/master/README.md)
- [Releases](https://github.com/carrot2/carrot2/releases)

---

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