Self-hosted service
Andersbakken/rtags avatar
Andersbakken/rtags

RTags indexes C++ with clang so follow-symbol and find-references work

A client/server indexer for c/c++/objc[++] with integration for Emacs based on clang.

1,848 stars258 forksC++GPL-3.0

At a glance

What is it?
RTags is a client/server indexer for C, C++ and limited ObjC that keeps a persistent file-based database of symbols, built on clang rather than a tag parser. Its value is real cross-reference navigation in Emacs, and its cost is a daemon that must be indexed before it is useful.
Who is it for?
C++ programmers editing large projects in Emacs, who can supply a JSON Compilation Database and tolerate an initial indexing pass, will get cross-reference navigation that etags and cscope do not offer. Anyone on a small single file codebase, or unwilling to run a background daemon and a compile command database, should stay with a plain tagger.
Can I use it commercially?
Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 7 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why clang parsing rather than tag file scanning

The README is blunt about the reason. Existing taggers such as GNU Global, cscope, etags and ctags "do a decent job for C" but fall short for C++, and the project attributes its own advantage entirely to clang: parsing C++ is described as an incredibly hard task, and RTags is said to improve on current tools only because clang exists. The name survives from an earlier plan. RTags was originally going to be built on Roberto Raggi's C++ parser, but he convinced the authors clang was the better route, and the name stuck.

That dependency shapes everything else. RTags does not scan text for identifiers. It runs the real C and C++ front end against each translation unit using the flags your build system actually uses, which is why the project starts by requiring a JSON Compilation Database. Your build system probably has a way to generate one, or you can use Bear. Each translation unit then yields declarations, definitions, references and symbol names with scope, including nested class and namespace scope, and those results land in a persistent file-based database rather than in the editor buffer.

The payoff is the two operations that matter most in a large C++ tree: follow-symbol and find-references. Rename-symbol is there too, and there is integration with clang fixits as defined in the clang diagnostics documentation.

The rdm daemon and rc client split

RTags is two processes. The daemon is `rdm`, started in the background, and the command line client is `rc`, which talks to it. The daemon holds the index; the client sends queries and prints answers. This is why the README's quickstart asks you to wait until rdm goes silent after indexing rather than starting work immediately: a partially indexed tree returns incomplete reference lists, and incomplete reference lists in a refactoring tool are worse than no answer.

The client is also what the Emacs package shells out to. The README does not describe a configuration file format, a daemon config file, or a set of tunable flags, so the settings surface appears to be command line arguments to `rdm` and `rc`. Anything beyond what the wiki documents would have to be read there.

The repository layout backs the split up. `src/` holds the sources, `bin/` is where the built binaries land and is the directory you point Emacs at, `cmake/` and `CMakeLists.txt` hold the build definition, `tests/` holds the test suite, `man/` holds manual pages, `share/` holds shared data such as the Emacs Lisp, `scripts/` holds helper scripts, and `web/` covers the hosted side. There is also `mcp-server/` at the top level, so the project is not confined to the Emacs integration, and `AGENTS.md` and `CHANGELOG.md` sit alongside `.clang-format` and `.travis.yml`.

Building rdm, then indexing a tree before you trust it

The quickstart assumes a compilation database already exists for your project. Clone the repository with submodules, configure with cmake and export compile commands, then build:

sh
git clone --recursive https://github.com/Andersbakken/rtags.git
cd rtags
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 .
make

The `--recursive` flag matters because the tree has a `.gitmodules`, so a plain clone leaves dependencies missing. Start the daemon in the background, then index the current tree and wait until it is silent:

sh
./bin/rdm &
sh
./bin/rc -J .

The `-J .` form is what the README uses to index a directory. Open a file at a specific line, for example `src/rdm.cpp` at line 74, then load the Emacs Lisp from inside Emacs:

sh
emacs +74:34 src/rdm.cpp
code
M-: (load-file "rtags.el") RET

Emacs then needs to find the client binary, which is what the `rtags-path` variable is for:

code
M-x set-variable RET rtags-path RET "../bin" RET

With that in place, `M-x rtags-find-symbol-at-point` jumps to the definition of `Server::instance()`, which is the worked example the README ends on. For people who would rather not build, tarball releases are published on the project's releases page.

Compiler errors through flymake, because the index knows the flags

One feature depends on something most taggers never learn: how your sources are actually compiled. Because RTags already has the real command line for each translation unit, it can produce the preprocessed output of the current source file on demand and drop it into a buffer, which is a fast way to answer "what does this macro expand to" without guessing.

The same knowledge feeds diagnostics. RTags integrates with flymake using clang's error and warning output, and since it continually reindexes files it considers dirty, the diagnostics you see in Emacs update as you type. The README does not describe how dirtiness is determined, whether it watches the filesystem or checks modification times on save, and it does not document a way to force a full reindex beyond issuing the index command again.

The Emacs side ships as separate MELPA packages rather than one. The list covers `rtags`, plus `rtags-xref` for cross-reference work, `ac-rtags`, `company-rtags` for completion, `flycheck-rtags`, `helm-rtags` for a Helm interface, and `ivy-rtags`. Each is distributed through MELPA with its own badge, which means you can take only the pieces you want instead of loading the whole integration.

The disclaimer the README prints itself

The README states plainly that RTags "is still under development and is not the most stable piece of software you'll ever find", and that the authors are constantly working on it. That is a warning from the authors rather than an outside assessment, and it should be read as part of the adoption decision rather than as a formality.

The codebase reflects a long history. The repository carries a `CHANGELOG.md`, and releases are numbered in the 2.4 range, with v2.42, v2.43 and v2.44 all published on 2026-02-07 within hours of each other. Three tags on one day reads like a maintenance burst rather than a release cadence, which means you may be picking up a tree that is more active than any single tag suggests. The last push to the repository was on 2026-10-12, so the code is moving.

Practical consequences follow from that stability note. Keep the daemon's index directory out of version control, and expect to restart `rdm` after an upgrade. Since the documentation lives in the project wiki rather than in the repository, the exact list of `rc` options and `rdm` flags is something you will have to look up there.

What RTags costs versus a plain tag file

The trade is explicit once you line the two approaches up. For C, the README says existing taggers such as GNU Global, cscope, etags and ctags do a decent job. For a C file of a few hundred lines, that is the right tool.

RTags inverts that. It needs a compilation database, which means your build system must be able to emit one. It needs the project to be indexed before any answer is trustworthy, which costs a full pass over the tree the first time and a smaller one whenever files change. It needs a daemon running. In exchange, references are resolved with a real parser, so overloads, templates, namespaces and inline definitions are handled by the compiler front end rather than by name matching.

For a large C++ codebase with heavy template use, that difference is the whole argument. The README also notes only limited support for ObjC and ObjC++, so a mixed Objective-C project gets partial coverage rather than full coverage.

Editorial conclusion

C++ programmers editing large projects in Emacs, who can supply a JSON Compilation Database and tolerate an initial indexing pass, will get cross-reference navigation that etags and cscope do not offer. Anyone on a small single file codebase, or unwilling to run a background daemon and a compile command database, should stay with a plain tagger. Before adopting, generate the compilation database for your real build, build RTags with the recursive clone above, and confirm that rdm indexes your tree to silence before trusting find-references results.

Frequently asked questions

What does RTags need before it can index a project?

A JSON Compilation Database for the project. The README says your build system probably has a way to generate one, or you can use something like Bear, because RTags parses sources with clang using your real compile flags.

How do I install RTags without building it from source?

Tarball releases are published on the project's GitHub releases page. The build route is a recursive git clone followed by cmake with -DCMAKE_EXPORT_COMPILE_COMMANDS=1 and make.

Which Emacs packages does RTags ship?

Separate MELPA packages: rtags, rtags-xref, ac-rtags, company-rtags, flycheck-rtags, helm-rtags and ivy-rtags. Each is published separately so you can take only the parts you need.

Does RTags support Objective-C?

Only partially. The project description says client/server indexer for c/c++/objc[++], and the README describes its ObjC and ObjC++ support as limited.

Is RTags stable enough for daily use?

The README itself says RTags is still under development and is not the most stable piece of software you will find. The last push was on 2026-10-12, so it is being worked on.

Official sources

  1. Andersbakken/rtags on GitHub
  2. License: GPL-3.0
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/andersbakken-rtags.svg)](https://hysenlabs.com/projects/andersbakken-rtags)

Was this useful?