← Back to list

⌘+click finally works in my Elixir projects in VS Code with ElixirLS

For years I coded Elixir in VS Code without go-to-definition. It was on my list, I never had the time. Today I sat down with the ElixirLS…

Felipe López · 2026-08-08 07:19 · 0 claps · 2.6 min read
#elixir #vscode #developer-experience
Open on Medium ↗
Wiki topics: CRY · Crypto & Web3

⌘+click finally works in my Elixir projects in VS Code with ElixirLS

For years I coded Elixir in VS Code without go-to-definition. It was on my list, I never had the time. Today I sat down with the ElixirLS output log and fixed it in an hour. Here’s everything, so you don’t spend the same hour.

Install

ElixirLS: Elixir support and debugger (JakeBecker.elixir-ls).

Shortcut on macOS is ⌘+click or F12. Ctrl+click is the context menu.

Where is your mix.exs?

This is the big one. ElixirLS looks for mix.exs in the root of the opened folder.

Case A — mix.exs in root

myapp_umbrella/
├── mix.exs
└── apps/

Opened with code myapp_umbrella. No config needed. Umbrellas work fine from their root.

Case B — mix.exs in a subdirectory

myapp-application-felipe/     <- opened folder
└── myapp_umbrella/
    ├── mix.exs
    └── apps/

The server starts, indexes nothing, and says so:

[warning] No mixfile found in project. Looked for mixfile at ".../mix.exs"
[info] Compile took 0 milliseconds
[ElixirLS WorkspaceSymbols] 0 symbols added to index in 0ms

Fix in .vscode/settings.json (workspace, not user):

{ "elixirLS.projectDir": "myapp_umbrella" }

Relative to the opened folder. Reload the window after.

Your only diagnostic

View > OutputElixirLS. One line matters:

[ElixirLS WorkspaceSymbols] N symbols added to index in Xms

N > 0 → navigation works. N = 0 → scroll up for the compile error.

Compile once from the terminal

Indexing needs a successful build. elixirLS.fetchDeps defaults to false, so the server won't fetch deps for you.

mix deps.get
MIX_ENV=test mix compile

MIX_ENV=test is what ElixirLS uses by default.

Version manager mismatch (mise / asdf)

ElixirLS activates mise from the opened folder, not from projectDir. In case B, if the project pins a version and the parent doesn't, you get two different Elixirs.

# Output panel
Running on elixir 1.18.4 (compiled with Erlang/OTP 27) on OTP 27
# terminal, inside the project
$ mise current
elixir 1.19.5-otp-28

Two Elixirs writing the same _build means endless recompilation and bogus errors.

Fix — mirror the pin in the opened folder:

mise use elixir@1.19.5-otp-28 erlang@28

Then clear the mixed artifacts once:

rm -rf _build .elixir_ls

Case A doesn’t have this problem.

rebar3

Any Erlang dependency needs rebar3:

Could not find "rebar3", which is needed to build dependency :otel_http
** (Mix.Error) httpc request failed with: ... builds.hex.pm ... tls_alert

Mix does not check your PATH. It looks inside MIX_HOME, and downloads a copy if missing — which fails behind a TLS-inspecting proxy or VPN.

With mise, MIX_HOME lives inside each Elixir install, so a registered rebar3 is per Elixir version. Switch versions, it's gone.

Per version:

brew install rebar3
mix local.rebar rebar3 "$(which rebar3)" --force

Global — [MIX_REBAR3](https://hexdocs.pm/mix/Mix.html) overrides the copy Mix installs and survives version switches. In ~/.zshrc:

export MIX_REBAR3=/opt/homebrew/bin/rebar3

And in VS Code user settings:

{
  "elixirLS.envVariables": { "MIX_REBAR3": "/opt/homebrew/bin/rebar3" }
}

envVariables is an object — workspace settings replace it wholesale, no key merge.

If you hit the TLS error, something is intercepting your HTTPS:

curl -v https://builds.hex.pm 2>&1 | grep -i issuer

Standard library navigation

Elixir sources not found (checking in /home/build/elixir).
Code navigation to Elixir modules disabled.

That path is baked in at CI build time. Jumping into Enum needs Elixir source on disk:

{ "elixirLS.stdlibSrcDir": "/path/to/elixir/lib/elixir/lib" }

Precompiled installs often ship no .ex files there — clone elixir-lang/elixir at your version tag instead. Independent of everything above; your own code navigates without it.

Documented non-bugs

  • No go-to-definition inside a Phoenix router scope block.
  • Fails when the cursor is at the very end of a symbol.
  • Requires an open workspace; single-file editing unsupported.

Restarting

Command Palette (⌘⇧P), cheapest first:

Command When ElixirLS: Restart language server Config change, or after fixing a build ElixirLS: Run mix clean Restart wasn't enough Quit, rm -rf .elixir_ls, reopen Last resort — full Dialyzer rebuild

Checklist

  1. mix.exs in the opened folder — or projectDir set
  2. Output panel Elixir version == terminal Elixir version
  3. mix deps.get && MIX_ENV=test mix compile passes
  4. rebar3 registered, or MIX_REBAR3 exported
  5. Non-zero symbol count

References


메타데이터
post_id
3d8faf8a35ee
slug
click-finally-works-in-my-elixir-projects-in-vs-code-with-elixirls-3d8faf8a35ee
url
https://medium.com/@felipelopezhamann/click-finally-works-in-my-elixir-projects-in-vs-code-with-elixirls-3d8faf8a35ee
canonical_url
https://medium.com/@felipelopezhamann/click-finally-works-in-my-elixir-projects-in-vs-code-with-elixirls-3d8faf8a35ee
author_url
https://medium.com/@felipelopezhamann
status
ok
fetched_at
2026-08-17 00:58:49