diff --git a/cli/cli.go b/cli/cli.go
index 44504de44ed..927ff4ed323 100644
--- a/cli/cli.go
+++ b/cli/cli.go
@@ -24,6 +24,7 @@ import (
 	"github.com/arduino/arduino-cli/cli/board"
 	"github.com/arduino/arduino-cli/cli/cache"
 	"github.com/arduino/arduino-cli/cli/compile"
+	"github.com/arduino/arduino-cli/cli/completion"
 	"github.com/arduino/arduino-cli/cli/config"
 	"github.com/arduino/arduino-cli/cli/core"
 	"github.com/arduino/arduino-cli/cli/daemon"
@@ -77,6 +78,7 @@ func createCliCommandTree(cmd *cobra.Command) {
 	cmd.AddCommand(board.NewCommand())
 	cmd.AddCommand(cache.NewCommand())
 	cmd.AddCommand(compile.NewCommand())
+	cmd.AddCommand(completion.NewCommand())
 	cmd.AddCommand(config.NewCommand())
 	cmd.AddCommand(core.NewCommand())
 	cmd.AddCommand(daemon.NewCommand())
diff --git a/cli/completion/completion.go b/cli/completion/completion.go
new file mode 100644
index 00000000000..ffe5472728e
--- /dev/null
+++ b/cli/completion/completion.go
@@ -0,0 +1,76 @@
+// This file is part of arduino-cli.
+//
+// Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
+//
+// This software is released under the GNU General Public License version 3,
+// which covers the main part of arduino-cli.
+// The terms of this license can be found at:
+// https://www.gnu.org/licenses/gpl-3.0.en.html
+//
+// You can be released from the requirements of the above licenses by purchasing
+// a commercial license. Buying such a license is mandatory if you want to
+// modify or otherwise use the software for commercial activities involving the
+// Arduino software without disclosing the source code of your own applications.
+// To purchase a commercial license, send an email to license@arduino.cc.
+
+package completion
+
+import (
+	"bytes"
+	"os"
+	"strings"
+
+	"github.com/arduino/arduino-cli/cli/errorcodes"
+	"github.com/arduino/arduino-cli/cli/feedback"
+	"github.com/spf13/cobra"
+)
+
+var (
+	completionNoDesc bool //Disable completion description for shells that support it
+)
+
+// NewCommand created a new `version` command
+func NewCommand() *cobra.Command {
+	command := &cobra.Command{
+		Use:       "completion [bash|zsh|fish] [--no-descriptions]",
+		ValidArgs: []string{"bash", "zsh", "fish"},
+		Args:      cobra.ExactArgs(1),
+		Short:     "Generates completion scripts",
+		Long:      "Generates completion scripts for various shells",
+		Example: "  " + os.Args[0] + " completion bash > completion.sh\n" +
+			"  " + "source completion.sh",
+		Run: run,
+	}
+	command.Flags().BoolVar(&completionNoDesc, "no-descriptions", false, "Disable completion description for shells that support it")
+
+	return command
+}
+
+func run(cmd *cobra.Command, args []string) {
+	if completionNoDesc && (args[0] == "bash" || args[0] == "zsh") {
+		feedback.Errorf("Error: command description is not supported by %v", args[0])
+		os.Exit(errorcodes.ErrGeneric)
+	}
+	switch args[0] {
+	case "bash":
+		cmd.Root().GenBashCompletion(os.Stdout)
+		break
+	case "zsh":
+		buf := new(bytes.Buffer)
+		cmd.Root().GenZshCompletion(buf)
+		// Next 3 lines are Hack, we'll wait new version of cobra with ZshV2Completion https://github.com/spf13/cobra/pull/1070
+		//insert escaping before [ and ]
+		s := strings.ReplaceAll(buf.String(), "[", "\\[")
+		s = strings.ReplaceAll(s, "]", "\\]")
+		s = strings.ReplaceAll(s, "\\[1\\]", "[1]") // revert the case
+		os.Stdout.WriteString(s)
+		break
+	case "fish":
+		buf := new(bytes.Buffer)
+		cmd.Root().GenFishCompletion(buf, !completionNoDesc)
+		// Next 2 lines are Hack, fixed here https://github.com/spf13/cobra/pull/1122
+		s := strings.ReplaceAll(buf.String(), "arduino-cli_comp", "arduino_cli_comp") //required because fish does not support env variables with "-" in the name
+		os.Stdout.WriteString(s)
+		break
+	}
+}
diff --git a/docs/command-line-completion.md b/docs/command-line-completion.md
new file mode 100644
index 00000000000..35455e7c90e
--- /dev/null
+++ b/docs/command-line-completion.md
@@ -0,0 +1,45 @@
+`arduino-cli` supports command-line completion (also known as *tab completion*) for basic commands.
+Currently only `bash`, `zsh`, `fish` shells are supported
+
+### Before you start
+In order to generate the file required to make the completion work you have to [install](installation.md) Arduino CLI first.
+
+### Generate the completion file
+To generate the completion file you can use `arduino-cli completion [bash|zsh|fish] [--no-descriptions]`.
+By default this command will print on the standard output (the shell window) the content of the completion file. To save to an actual file use the `>` redirect symbol.
+
+### Bash
+Use `arduino-cli completion bash > arduino-cli.sh` to generate the completion file.
+At this point you can move that file in `/etc/bash_completion.d/` (root access is required) with `sudo mv arduino-cli.sh /etc/bash_completion.d/`.
+
+A not recommended alternative is to source the completion file in `.bashrc`.
+
+Remember to open a new shell to test the functionality
+
+### Zsh
+Use `arduino-cli completion zsh > _arduino-cli` to generate the completion file.
+At this point you can place the file in a directory listed in your `fpath` if you have already created a directory to store your completion.
+
+Or if you want you can create a directory, add it to your `fpath` and copy the file in it:
+
+1. `mkdir ~/completion_zsh`
+2. add `fpath=($HOME/completion_zsh $fpath)` at the beginning of your `.zshrc` file
+3. `mv _arduino-cli ~/completion_zsh/`
+
+Remember to open a new shell to test the functionality
+
+*N.B.*
+The Zsh completion is working with [Oh-My-Zsh](https://ohmyz.sh/) but not with [Prezto](https://github.com/sorin-ionescu/prezto) (the zsh completion system is working in a different way than classic zsh). But hopefully it will be fixed in the future
+
+### Fish
+Use `arduino-cli completion fish > arduino-cli.fish` to generate the completion file.
+At this point you can place the file in `~/.config/fish/completions` as stated in the [official documentation](http://fishshell.com/docs/current/index.html#where-to-put-completions).
+Remember to create the directory if it's not already there `mkdir -p ~/.config/fish/completions/` and then place the completion file in there with `mv arduino-cli.fish ~/.config/fish/completions/`
+
+Remember to open a new shell to test the functionality
+
+#### Disabling command and flag descriptions
+By default fish completion has command and flag description enabled by default. If you want to disable this behaviour you can simply pass the `--no-descriptions` flag when calling `completion` command and the generated file will not have descriptions
+
+*N.B.*
+This flag is not compatible with bash or zsh
diff --git a/docsgen/go.mod b/docsgen/go.mod
index 6ef7b4955a5..331cf3cb951 100644
--- a/docsgen/go.mod
+++ b/docsgen/go.mod
@@ -6,5 +6,5 @@ replace github.com/arduino/arduino-cli => ../
 
 require (
 	github.com/arduino/arduino-cli v0.0.0
-	github.com/spf13/cobra v0.0.6
+	github.com/spf13/cobra v1.0.0
 )
diff --git a/go.mod b/go.mod
index fa398bf170e..e1b824f9251 100644
--- a/go.mod
+++ b/go.mod
@@ -35,7 +35,7 @@ require (
 	github.com/schollz/closestmatch v2.1.0+incompatible
 	github.com/segmentio/stats/v4 v4.5.3
 	github.com/sirupsen/logrus v1.4.2
-	github.com/spf13/cobra v0.0.5
+	github.com/spf13/cobra v1.0.0
 	github.com/spf13/jwalterweatherman v1.0.0
 	github.com/spf13/viper v1.6.2
 	github.com/stretchr/testify v1.4.0
diff --git a/go.sum b/go.sum
index 52b9bdc331c..95aa17bc879 100644
--- a/go.sum
+++ b/go.sum
@@ -42,6 +42,8 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
 github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
+github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
+github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 github.com/creack/goselect v0.1.1 h1:tiSSgKE1eJtxs1h/VgGQWuXUP0YS4CDIFMp6vaI1ls0=
 github.com/creack/goselect v0.1.1/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
 github.com/daaku/go.zipexe v1.0.0 h1:VSOgZtH418pH9L16hC/JrgSNJbbAL26pj7lmD1+CGdY=
@@ -171,6 +173,8 @@ github.com/rifflock/lfshook v0.0.0-20180920164130-b9218ef580f5/go.mod h1:GEXHk5H
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
 github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
 github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
+github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
+github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiyyjYS17cCYRqP13/SHk=
 github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
 github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e h1:uO75wNGioszjmIzcY/tvdDYKRLVvzggtAmmJkn9j4GQ=
@@ -179,6 +183,8 @@ github.com/segmentio/objconv v1.0.1 h1:QjfLzwriJj40JibCV3MGSEiAoXixbp4ybhwfTB8RX
 github.com/segmentio/objconv v1.0.1/go.mod h1:auayaH5k3137Cl4SoXTgrzQcuQDmvuVtZgS0fb1Ahys=
 github.com/segmentio/stats/v4 v4.5.3 h1:Y/DSUWZ4c8ICgqJ9rQohzKvGqGWbLPWad5zmxVoKN+Y=
 github.com/segmentio/stats/v4 v4.5.3/go.mod h1:LsaahUJR7iiSs8mnkvQvdQ/RLHAS5adGLxuntg0ydGo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
+github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@@ -194,12 +200,15 @@ github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
+github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8=
+github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
 github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
 github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
 github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
diff --git a/mkdocs.yml b/mkdocs.yml
index af169843596..0e2e2375a7c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -56,6 +56,7 @@ nav:
   - Documentation Home: index.md
   - installation.md
   - getting-started.md
+  - command-line-completion.md
   - CONTRIBUTING.md
   - FAQ.md
   - Command reference:
@@ -68,6 +69,7 @@ nav:
     - cache: commands/arduino-cli_cache.md
     - cache clean: commands/arduino-cli_cache_clean.md
     - compile: commands/arduino-cli_compile.md
+    - completion: commands/arduino-cli_completion.md
     - config: commands/arduino-cli_config.md
     - config dump: commands/arduino-cli_config_dump.md
     - config init: commands/arduino-cli_config_init.md
diff --git a/test/test_completion.py b/test/test_completion.py
new file mode 100644
index 00000000000..3f6bc303534
--- /dev/null
+++ b/test/test_completion.py
@@ -0,0 +1,63 @@
+# This file is part of arduino-cli.
+#
+# Copyright 2020 ARDUINO SA (http://www.arduino.cc/)
+#
+# This software is released under the GNU General Public License version 3,
+# which covers the main part of arduino-cli.
+# The terms of this license can be found at:
+# https://www.gnu.org/licenses/gpl-3.0.en.html
+#
+# You can be released from the requirements of the above licenses by purchasing
+# a commercial license. Buying such a license is mandatory if you want to modify or
+# otherwise use the software for commercial activities involving the Arduino
+# software without disclosing the source code of your own applications. To purchase
+# a commercial license, send an email to license@arduino.cc.
+
+import pytest
+
+def test_completion_no_args(run_command):
+    result = run_command("completion")
+    assert not result.ok
+    assert "Error: accepts 1 arg(s), received 0" in result.stderr
+    assert result.stdout == ""
+
+def test_completion_bash(run_command):
+    result = run_command("completion bash")
+    assert result.ok
+    assert result.stderr == ""
+    assert "_arduino-cli_root_command()" in result.stdout
+    assert "__start_arduino-cli()" in result.stdout
+
+def test_completion_zsh(run_command):
+    result = run_command("completion zsh")
+    assert result.ok
+    assert result.stderr == ""
+    assert "#compdef _arduino-cli arduino-cli" in result.stdout
+    assert "function _arduino-cli" in result.stdout
+
+def test_completion_fish(run_command):
+    result = run_command("completion fish")
+    assert result.ok
+    assert result.stderr == ""
+    assert "# fish completion for arduino-cli" in result.stdout
+    assert "function __arduino-cli_perform_completion" in result.stdout
+
+def test_completion_bash_no_desc(run_command):
+    result = run_command("completion bash --no-descriptions")
+    assert not result.ok
+    assert result.stdout == ""
+    assert "Error: command description is not supported by bash" in result.stderr
+
+def test_completion_zsh_no_desc(run_command):
+    result = run_command("completion zsh --no-descriptions")
+    assert not result.ok
+    assert result.stdout == ""
+    assert "Error: command description is not supported by zsh" in result.stderr
+
+def test_completion_fish_no_desc(run_command):
+    result = run_command("completion fish --no-descriptions")
+    assert result.ok
+    assert result.stderr == ""
+    assert "# fish completion for arduino-cli" in result.stdout
+    assert "function __arduino-cli_perform_completion" in result.stdout
+    assert "__completeNoDesc" in result.stdout
\ No newline at end of file