# ycmd: A Code Completion and Navigation Server

> ycmd gives editor clients access to identifier completion, semantic completion, diagnostics, and code navigation through a Python-based server. Its language support depends on separate engines and toolchains, making engine configuration and HMAC verification central to adoption.

**ycm-core/ycmd** — A code-completion & code-comprehension server

- Repository: https://github.com/ycm-core/ycmd
- Website: https://ycm-core.github.io/ycmd/
- Stars: 1,740 · Forks: 776
- Language: C++
- License: GPL-3.0
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/ycm-core-ycmd

## Why ycmd Exists Between Editors and Language Backends

ycmd solves the editor integration side of code intelligence. It was split from YouCompleteMe so clients outside Vim could call the same completion and code-comprehension capabilities through APIs. The intended users are editor client developers and users whose editor needs completion, semantic GoTo commands, or language-specific diagnostics.

The server is not a text editor and does not present the completion interface directly. It accepts requests from a client, selects an appropriate completion engine, and returns structured results over an API documented with Swagger. The repository identifies clients for Vim, Emacs, Atom, Sublime Text, Kakoune, Visual Studio Code, Geany, and GNU nano, although the feature set exposed by those clients can differ.

This split has a practical consequence. An editor integration must implement request handling, file-state updates, result presentation, and response validation. ycmd can then coordinate identifier collection, semantic analysis, diagnostics, and navigation without embedding all of those mechanisms in the editor. The API documentation and `examples/example_client.py` are therefore more relevant to evaluators than the list of client names.

## How ycmd Chooses and Combines Completion Engines

The simplest engine collects identifiers from the current file, previously supplied files of the same filetype, and tags files produced by ctags. It is non-semantic and also participates in filepath completion. This path addresses the common case in which a developer knows the identifier but wants the editor to supply the rest of its name.

Semantic engines provide type-aware results. The documented engines include clangd for C-family languages, Jedi for Python, OmniSharp for C#, gopls for Go and GoTo definition, TSServer for JavaScript and TypeScript, jdt.ls for Java, and RLS for Rust. The server decides which engine fits the request. In some situations, it queries multiple engines, combines their results, and sends the merged result to the client.

Semantic requests are normally triggered by characters inserted into source code. A dot after an expression can trigger member lookup, while text already typed after the trigger becomes the completion query. Clients can send `force_semantic: true`, but the README advises doing that only when the user explicitly requests semantic completion. Semantic engines can be slow, and ycmd avoids invoking them when identifier completion is sufficient.

Results are not filtered as ordinary prefixes. The input must be a subsequence of a candidate, meaning that its characters occur in the candidate in order without necessarily being adjacent. For example, `abc` matches `xaybgc` but not `xbyxaxxc`. The subsequent ranking system orders the remaining candidates using detailed scoring that the README describes only in broad terms.

## Ubuntu Build and the Example Client's First Request Flow

The documented build path is for Ubuntu Linux and requires Python 3.12.0 or later. Install the basic compiler and Python development packages first. These commands install the minimum documented dependencies and prepare Python headers for the build.

```bash
sudo apt install build-essential cmake python3-dev
```

Language support is optional, so install only the toolsets required for the languages handled by the editor. The README lists separate packages for Go, JavaScript and TypeScript, C#, and Java.

```bash
sudo apt install golang-go
sudo apt install npm
sudo apt install mono-devel
sudo apt install openjdk-8-jre
```

After cloning the repository, initialize the nested third-party dependencies recorded as Git submodules. This command is required because the build depends on repository-managed source trees.

```bash
git submodule update --init --recursive
```

Build all available components with the repository's Python build script. The README also directs developers to `python3 build.py --help` for the specific completers that can be selected.

```bash
python3 build.py --all
```

The README does not provide a single server-start command or a canned editor session. It directs developers to the API documentation, `examples/example_client.py`, and the examples README for the exact interaction flow. Those files are the correct starting points for a first real use because client startup requires a shared secret and the API requires authenticated request and response bodies.

## HMAC, UTF-8, and Byte Offsets Define the Client Contract

Every request sent to ycmd must include an HMAC in the `x-ycm-hmac` HTTP header. The server and client share a secret supplied when the server starts. The digest algorithm is SHA-256, and the signature covers the request or response body. Responses also carry an HMAC that clients must verify before using their contents.

This is a strict integration requirement rather than an optional transport feature. A client that omits request authentication will not satisfy the documented API, and one that ignores response authentication fails to follow its security contract. `examples/example_client.py` is identified by the project as the reference for implementing the calculation and verification.

The payload rules are equally specific. Strings are UTF-8 encoded, lines end with `\n`, and line and column values are 1-based byte offsets rather than Unicode codepoint offsets. File paths must be complete absolute paths. An editor that tracks character indexes as Unicode codepoints cannot forward those values directly. It must translate its positions according to the UTF-8 byte representation used by the protocol.

These constraints favor clients designed around ycmd's wire protocol. A lightweight integration that treats positions as opaque integers may appear simple but can report incorrect locations for text containing multibyte characters. The examples should be inspected for the complete request lifecycle, including how file contents and authentication data are prepared.

## Language Coverage Comes with Toolchain Boundaries

ycmd provides a server layer across multiple completion mechanisms, but it does not make every language equally self-contained. C-family completion depends on clangd, Python uses Jedi, C# uses OmniSharp, Go uses gopls, JavaScript and TypeScript use TSServer, Java uses jdt.ls, and Rust uses RLS. The README also says that diagnostics are available for certain filetypes, so completion coverage should not be read as identical diagnostic coverage.

This architecture is useful for editors that want one API boundary while delegating language knowledge to established engines. It is a poor fit for a language not covered by the documented engine set, or for a deployment that disallows the associated runtime and system dependencies. Identifier completion and filepath completion remain available, but their results do not replace semantic type information.

The project also has no GitHub releases. Maintenance can be assessed from repository activity instead: it is not archived, and the last push was on 2026-10-16. That does not define compatibility for every backend, since engine upgrades can change behavior independently of ycmd itself. An adopter must check the documented engine requirements and build options for the exact languages in use.

Upgrades also involve repository-managed components. A clean update changes `ycmd` and its submodules, while an environment upgrade may need matching compiler, Python, runtime, and language packages. The supported compiler list is specific: GCC 8 or later, Clang 7 or later, or Microsoft Visual Studio 2017 version 15.7 or later.

## GPL-3.0 Distribution Choices and the Direct Editor Alternative

The repository identifies ycmd under GPL-3.0 and includes `COPYING.txt`. Teams planning to redistribute ycmd, bundle it with an editor distribution, or modify and ship it should review those license files for the obligations that apply to their distribution model. This is a compliance consideration, not legal advice, and the license should be checked alongside any client or packaging terms.

A direct alternative is to integrate each language server in the editor through the editor's own LSP implementation. That approach avoids adding ycmd's extra process and API translation layer when the editor already supports clangd, gopls, jdt.ls, or another required backend. The tradeoff is that capabilities and behavior come from separate integrations rather than ycmd's unified request surface.

The direct route also changes the authentication burden. ycmd clients must implement its `x-ycm-hmac` exchange, while an editor's native LSP client follows that editor's transport behavior instead. For an editor with mature built-in language-server support, that simpler architecture may be preferable. ycmd is more relevant when an editor lacks native language-server support, needs the same backend behavior across multiple editors, or intends to expose the APIs described in its Swagger documentation.

## Conclusion

Adopt ycmd when an editor client needs a shared completion and navigation API and the required language engines are acceptable dependencies. Do not choose it as a standalone editor or for an unsupported language without first locating another backend. Verify Python 3.12 compatibility, engine dependencies, absolute-path and byte-offset handling, and HMAC verification in the client before integration.

## FAQ

### How do I build ycmd on Ubuntu?

Use Python 3.12.0 or later, install the documented build dependencies, initialize the Git submodules, and run `python3 build.py --all`. The README provides separate package commands for the optional language toolchains.

### Does ycmd provide semantic completion for Python and compiled languages?

The documented semantic engines include Jedi for Python and clangd for C-family languages. Other documented engines cover C#, Go, JavaScript, TypeScript, Java, and Rust.

### How must a client authenticate requests to ycmd?

Every request must include an SHA-256 HMAC in the `x-ycm-hmac` header, using the secret shared with the server. Clients must also verify the HMAC included in responses, as shown by `examples/example_client.py`.

## Sources

- [Issues](https://github.com/ycm-core/ycmd/issues)
- [License: GPL-3.0](https://github.com/ycm-core/ycmd/blob/master/LICENSE)
- [Project website](https://ycm-core.github.io/ycmd/)
- [README](https://github.com/ycm-core/ycmd/blob/master/README.md)
- [ycm-core/ycmd on GitHub](https://github.com/ycm-core/ycmd)

---

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