You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Disabling completion does not reduce binary size #2291
Enabling completion doesn't increase the size of the binary.
My urfave/cli version is
( Put the version of urfave/cli that you are using here )
Checklist
Are you running the latest v3 release? The list of releases is here.
Did you check the manual for your release? The v3 manual is here
Did you perform a search about this problem? Here's the GitHub guide about searching.
Dependency Management
My project is using go modules.
My project is using vendoring.
My project is automatically downloading the latest version.
I am unsure of what my dependency management setup is.
Describe the bug
A clear and concise description of what the bug is.
To reproduce
Describe the steps or code required to reproduce the behavior
Observed behavior
What did you see happen immediately after the reproduction steps
above?
Expected behavior
What would you have expected to happen immediately after the
reproduction steps above?
Additional context
Add any other context about the problem here.
If the issue relates to a specific open source GitHub repo, please
link that repo here.
If you can reproduce this issue with a public CI system, please
link a failing build here.
Want to fix this yourself?
We'd love to have more contributors on this project! If the fix for
this bug is easily explained and very small, feel free to create a
pull request for it.
@dearchap maybe making the whole mechanism optional would save more? While 10k doesn't seem much, if every dependency adds 10k, and then there are the same templates in each Go binary.. I don't know, maybe it doesn't worth it. In the past I thought every tool should just generate cli JSON and let shell harness figure out how to transform it into its own format.
I dug into why disabling EnableShellCompletion doesn't shrink the binary — root cause is a dead-code-elimination limitation, not a config bug. buildCompletionCommand (command_setup.go) is only called when cmd.EnableShellCompletion is true, but that's a runtime check inside an if. The function itself — plus everything it references, including the bash/zsh/fish/powershell completion templates — is still statically reachable from setupCommandGraph, which every Command goes through unconditionally. The Go linker can only strip code that's provably unreachable at compile time; a runtime boolean doesn't help it. On top of that, ToFishCompletion and similar helpers are exported methods on *Command, so they're part of the public API surface and get kept regardless of whether the user's own code ever calls them. So as long as this machinery exists unconditionally in the package (even behind a runtime if false), it ships in every binary that imports cli, whether or not completion is enabled. A real fix needs something structural — e.g. gating completion behind a build tag, or moving it into an opt-in subpackage users only import if they want completion support — rather than a runtime flag. Both are breaking-ish changes to the current API, so before I put together a PR: is this a direction maintainers would consider, or is there a narrower fix in mind?
Activity
dearchap commentedon Jun 6, 2026
@abitrolly so what is the problem. Do we want to remove the https://github.com/urfave/cli/tree/main/autocomplete FS ? It will save around 10Kb or so I think. Whats the point ??
abitrolly commentedon Jun 6, 2026
@dearchap maybe making the whole mechanism optional would save more? While 10k doesn't seem much, if every dependency adds 10k, and then there are the same templates in each Go binary.. I don't know, maybe it doesn't worth it. In the past I thought every tool should just generate cli JSON and let shell harness figure out how to transform it into its own format.
/cc @kolyshkin
Chris-cez commentedon Nov 6, 2026
I dug into why disabling EnableShellCompletion doesn't shrink the binary — root cause is a dead-code-elimination limitation, not a config bug. buildCompletionCommand (command_setup.go) is only called when cmd.EnableShellCompletion is true, but that's a runtime check inside an if. The function itself — plus everything it references, including the bash/zsh/fish/powershell completion templates — is still statically reachable from setupCommandGraph, which every Command goes through unconditionally. The Go linker can only strip code that's provably unreachable at compile time; a runtime boolean doesn't help it. On top of that, ToFishCompletion and similar helpers are exported methods on *Command, so they're part of the public API surface and get kept regardless of whether the user's own code ever calls them. So as long as this machinery exists unconditionally in the package (even behind a runtime if false), it ships in every binary that imports cli, whether or not completion is enabled. A real fix needs something structural — e.g. gating completion behind a build tag, or moving it into an opt-in subpackage users only import if they want completion support — rather than a runtime flag. Both are breaking-ish changes to the current API, so before I put together a PR: is this a direction maintainers would consider, or is there a narrower fix in mind?