How to list top biggest library dependencies of my app?

Is there a way to list the top biggest libraries that my app depend on?

I would like to reduce the full compilation time of my app by removing its biggest dependencies. I suspect some of them aren’t needed anymore, but there are so many libraries that I can’t afford to analyze one by one. So I would like to start from the biggest.

Is it possible?

1 Like

What do you mean? LOC, compilation time or number of dependencies of each hex package? Have you tried mix deps.tree?

File size does not always correlate to compile times, but here’s a quick and dirty script that sorts each dependency by the total file size of the ex and erl files.

mix run -e '
paths = Mix.Project.deps_paths()

Mix.Project.deps_tree()
|> Enum.map(fn {app, deps} ->
  app_size =
    paths
    |> Map.get(app)
    |> List.wrap()
    |> Mix.Utils.extract_files("*")
    |> Enum.map(&File.stat!(&1).size)
    |> Enum.sum()

  deps_size =
    deps
    |> Enum.map(&Map.get(paths, &1))
    |> Mix.Utils.extract_files("*")
    |> Enum.map(&File.stat!(&1).size)
    |> Enum.sum()

  {app, %{deps: deps, app: app_size, total: app_size + deps_size}}
end)
|> Enum.sort_by(&elem(&1, 1).app, &>=/2)
|> IO.inspect(limit: :infinity)
'

This code should not be recommended since it uses a private API which could changed in any next Elixir release.

Given that Elixir macros mean there can be arbitrary code execution at compile time, size of library (in lines of code) is an unreliable predictor of compile time.

In addition, since dependencies are compiled once I’m not sure that you will gain any material compile time improvements due to pruning (assumes you are caching dependencies in CI).

2 Likes

I have never once used them but since 1.11 Elixir has compiler tracers that could allow you to e.g. track which dependency takes longest to compile – if that’s the problem you are solving for.

Though I really think we have an XY problem here and you should give us an idea of your project’s structure so we can help you reduce compilation time or a runtime bottleneck.