[Proposal] Add `mix deps.add` and `mix deps.remove` commands

20 views
Skip to first unread message

Dairon Medina Caro

unread,
Feb 27, 2026, 10:40:30 AM (yesterday) Feb 27
to elixir-lang-core
This isn't a criticism of Mix's current design - I like that `mix.exs` is transparent and editable. But for the common case of adding or removing a dependency, there's unnecessary friction compared to other modern package managers like cargo in Rust or uv in Python.

Adding a dependency currently means: open `mix.exs` → find the `deps` function → remember the tuple syntax → look up the version format → add the entry → save → run `mix deps.get`.

For complex cases with conditional logic or special constraints, editing the file directly makes sense. But for "add this package from Hex" it's more ceremony than needed.

Proposal

Add two new Mix tasks: `mix deps.add` and `mix deps.remove` that handle the common case of adding or removing dependencies from your project.

### `mix deps.add`

Adds one or more dependencies to your `mix.exs` file and fetches them.

```bash
# Add latest version from Hex
mix deps.add phoenix

# Add with version requirement
mix deps.add phoenix ~> 1.7

# Add from git
mix deps.add phoenix --git https://github.com/phoenixframework/phoenix.git

# Add from GitHub (shorthand)
mix deps.add phoenix --github phoenixframework/phoenix --tag v1.7.0

# Add from local path
mix deps.add my_lib --path ../my_lib

# Add with options
mix deps.add phoenix --only dev
mix deps.add benchee --only test --optional
mix deps.add jason --override

# Add to umbrella app
mix deps.add my_app --in-umbrella

# Mix and match multiple packages
mix deps.add phoenix ecto_sql postgrex
```

### `mix deps.remove`

Removes one or more dependencies from your `mix.exs` file.

```bash
# Remove a package
mix deps.remove phoenix

# Remove multiple packages
mix deps.remove phoenix ecto postgrex
```

## Options

The commands would need to support Mix's existing dependency options:

- Source: `--git`, `--github`, `--path`, `--in-umbrella`
- Git: `--tag`, `--branch`, `--ref`, `--sparse`, `--subdir`, `--submodules`
- Environment: `--only`, `--targets`, `--optional`, `--override`, `--runtime`, `--env`
- Hex: `--hex`, `--repo`
- Behavior: `--no-fetch` (skip `mix deps.get` after modifying `mix.exs`)

## More Examples

```bash
# Test-only dependency
mix deps.add ex_machina --only test

# Optional dependency (for library authors)
mix deps.add hackney --optional

# Override conflicting transitive dependency
mix deps.add tesla --override

# Local development
mix deps.add my_lib --path ~/projects/my_lib

# Umbrella app
cd apps/my_workers && mix deps.add my_core --in-umbrella

# Git with specific options
mix deps.add phoenix_live_view --github phoenixframework/phoenix_live_view --tag v1.0.0
```

The tricky part is modifying `mix.exs` while preserving formatting, comments, and custom logic. AST manipulation can handle the parsing, but needs care with formatting.

For version resolution, when no version is specified, query Hex for the latest and use `~> MAJOR.MINOR`.

The generated deps should look like hand-written ones:
```elixir
{:phoenix, "~> 1.7"}
{:credo, "~> 1.6", only: [:dev, :test], runtime: false}
{:my_lib, path: "../my_lib"}
```

These commands are for common cases. Complex scenarios with conditional logic still need direct `mix.exs` editing - that's fine. This is about making "add this Hex package" frictionless, not about replacing the file-based approach entirely.

I'm happy to discuss further or implement this if the proposal seems reasonable.

Aaron Ross

unread,
Feb 27, 2026, 1:07:46 PM (yesterday) Feb 27
to elixir-lang-core
I'd love to see this implemented.

When adding a dependency, most of the time I just want the latest version. Having the CLI fetch that without having to navigate to hex.pm myself would be really nice to have!

Agree that `~> MAJOR.MINOR` is the correct version format to default to when adding.

Jean Klingler

unread,
Feb 27, 2026, 4:01:25 PM (yesterday) Feb 27
to elixir-l...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/2681fb9a-0f7f-4020-a635-8c55b42c14e9n%40googlegroups.com.

Christopher Keele

unread,
Feb 27, 2026, 4:06:20 PM (yesterday) Feb 27
to elixir-lang-core
My recommendation would be `~> MAJOR.MINOR.PATCH` by default and `~> MAJOR.MINOR` for `--only dev`/`--only test`.

Don't forget to consider `Mix.target()` in your proposal, and multiple envs. Would `--only-env`/`--only-target` be better, or just `--env`/`--target`? Comma separated for multiple, or repeated flag, or both?

Also consider how this would work for already specified dependences. Refusal to proceed? Update the version? What about with disjoint sets of envs/targets? Etc.

Zach Daniel

unread,
Feb 27, 2026, 4:38:05 PM (yesterday) Feb 27
to elixir-l...@googlegroups.com
Yep, I would personally suggest looking into igniter. In addition to supporting rich installers via `mix igniter.install`, it also supports just `mix igniter.add` and `mix igniter.remove` etc.


--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/9293826d-e802-43c5-ba7a-bbfd6562014en%40googlegroups.com.

Dairon Medina Caro

unread,
Feb 27, 2026, 4:47:22 PM (yesterday) Feb 27
to elixir-l...@googlegroups.com
I see now, haven't used igniter other than for setting up Oban. The mix tasks do exactly what I thought. While it would be nice to have in the Elixir core these works so I guess nothing to see here :P. Thanks all!

To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.

--
You received this message because you are subscribed to a topic in the Google Groups "elixir-lang-core" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/elixir-lang-core/LRufQItVlVE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/elixir-lang-core/mm5ey1d0.ca7e9ec5-dbf1-46cd-af23-8332b389c830%40we.are.superhuman.com.


--
created with MySignature.io
Dairon Medina Caro
Freelance Software Developer
created with MySignature.iocreated with MySignature.io



Reply all
Reply to author
Forward
0 new messages