diff --git a/NodeApp/src/commander/completion/CompletionCommand.ts b/NodeApp/src/commander/completion/CompletionCommand.ts
index f0b71909c73ce320e1e71d564582d76e1d7903b9..ba4f3cfe026a2da2f66992aa2ec535c35afcf5b5 100644
--- a/NodeApp/src/commander/completion/CompletionCommand.ts
+++ b/NodeApp/src/commander/completion/CompletionCommand.ts
@@ -1,9 +1,7 @@
-import CommanderCommand        from '../CommanderCommand';
-import CompletionBashCommand   from './subcommands/CompletionBashCommand';
-import CompletionFishCommand   from './subcommands/CompletionFishCommand';
-import CompletionZshCommand    from './subcommands/CompletionZshCommand';
-import CompletionGetCommand    from './subcommands/CompletionGetCommand';
-import CompletionScriptCommand from './subcommands/CompletionScriptCommand';
+import CommanderCommand              from '../CommanderCommand';
+import CompletionCreateUpdateCommand from './subcommands/CompletionCreateUpdateCommand';
+import CompletionGetCommand          from './subcommands/CompletionGetCommand';
+import CompletionScriptCommand       from './subcommands/CompletionScriptCommand';
 
 
 class CompletionCommand extends CommanderCommand {
@@ -15,10 +13,7 @@ class CompletionCommand extends CommanderCommand {
     }
 
     protected defineSubCommands() {
-        CompletionBashCommand.registerOnCommand(this.command);
-        CompletionFishCommand.registerOnCommand(this.command);
-        CompletionZshCommand.registerOnCommand(this.command);
-
+        CompletionCreateUpdateCommand.registerOnCommand(this.command);
         CompletionGetCommand.registerOnCommand(this.command);
         CompletionScriptCommand.registerOnCommand(this.command);
     }
diff --git a/NodeApp/src/commander/completion/subcommands/CompletionBashCommand.ts b/NodeApp/src/commander/completion/subcommands/CompletionBashCommand.ts
deleted file mode 100644
index 6e7e6f7849c0260c55ff42bbac6014ab7e3c6d6b..0000000000000000000000000000000000000000
--- a/NodeApp/src/commander/completion/subcommands/CompletionBashCommand.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import CommanderCommand from '../../CommanderCommand';
-import path             from 'path';
-import os               from 'os';
-import { updateRcFile } from '../../../helpers/AutoCompletionHelper';
-
-
-class CompletionBashCommand extends CommanderCommand {
-    protected commandName: string = 'bash';
-
-    private readonly bashrcPath = path.join(os.homedir(), '.bashrc');
-    private readonly completionCommand = `
-# Added by DojoCLI
-eval "$(dojo completion script bash)"
-`;
-
-    protected defineCommand() {
-        this.command.description('generate bash completion')
-            .action(this.commandAction.bind(this));
-    }
-
-    protected async commandAction(): Promise<void> {
-        updateRcFile('bash', this.bashrcPath, this.completionCommand);
-    }
-}
-
-
-export default new CompletionBashCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/completion/subcommands/CompletionCreateUpdateCommand.ts b/NodeApp/src/commander/completion/subcommands/CompletionCreateUpdateCommand.ts
new file mode 100644
index 0000000000000000000000000000000000000000..edc521942681dd07339e1607cc2423eeaa9586d7
--- /dev/null
+++ b/NodeApp/src/commander/completion/subcommands/CompletionCreateUpdateCommand.ts
@@ -0,0 +1,101 @@
+import CommanderCommand                                                 from '../../CommanderCommand';
+import { Option }                                                       from 'commander';
+import { generateFishCompletion, getRoot, tryRenameFile, updateRcFile } from '../../../helpers/AutoCompletionHelper';
+import os, { homedir }                                                  from 'os';
+import path                                                             from 'path';
+import ora                                                              from 'ora';
+import fs                                                               from 'fs-extra';
+import TextStyle                                                        from '../../../types/TextStyle';
+
+
+class CompletionCreateUpdateCommand extends CommanderCommand {
+    protected commandName: string = 'create';
+    protected aliasNames: Array<string> = [ 'update' ];
+
+
+    protected defineCommand() {
+        this.command.description('generate shell completion')
+            .addOption(new Option('-s, --shell <shell>', 'shell type').choices([ 'bash', 'zsh', 'fish' ]).makeOptionMandatory(true))
+            .addOption(new Option('-f, --file <filename>', '(only for fish shell)').implies({ shell: 'fish' }))
+            .addOption(new Option('-y, --force', 'don\'t ask for file overwrite confirmation (only for fish shell)').implies({ shell: 'fish' }))
+            .action(this.commandAction.bind(this));
+    }
+
+    private bash() {
+        const completionCommand = `
+# Added by DojoCLI
+eval "$(dojo completion script bash)"
+`;
+        updateRcFile('bash', path.join(os.homedir(), '.bashrc'), completionCommand);
+    }
+
+    private zsh() {
+        const completionCommand = `
+# Added by DojoCLI
+source <(dojo completion script zsh)
+`;
+        updateRcFile('zsh', path.join(homedir(), '.zshrc'), completionCommand);
+    }
+
+    /* The completion command must do the following:
+       - if a file is provided:
+            - if force is not enabled:
+                - check if the file exists:
+                    - if it exists, prompt the user that it will be erased
+                        - if ok is given write the file and prompt that a backup has been created
+            - else create the file containing the completion
+        - else
+            - if force is not enabled:
+                - check if the default file exists:
+                    - if it exists, prompt the user that it will be erased:
+                        - if ok is given write the file and prompt that a backup has been created
+            - else
+                - create the file containing the completion
+    */
+    private async fish(options: { file: string, force: boolean }) {
+        const filePath = path.resolve(options.file ?? path.join(os.homedir(), '.config/fish/completions/dojo.fish'));
+        const showInstructions = !!options.file;
+        if ( !(await tryRenameFile(filePath, options.force)) ) { // means renaming was interrupted
+            return;
+        }
+
+        const spinner: ora.Ora = ora(`Writing fish completion in ${ filePath }...`).start();
+
+        try {
+            fs.mkdirsSync(path.dirname(filePath));
+
+            fs.writeFileSync(filePath, generateFishCompletion(getRoot(this.command)));
+
+            spinner.succeed(`Fish completion successfully written in ${ filePath }.`);
+            if ( showInstructions ) {
+                const cpCommand = ` cp -i ${ filePath } ~/.config/fish/completions  # interactive cp to avoid accidents `;
+                console.log(`
+The easiest way to install the completion is to copy the ${ TextStyle.CODE(filePath) } into the ${ TextStyle.CODE('~/.config/fish/completions') } directory.
+
+${ TextStyle.CODE(cpCommand) }`);
+            }
+        } catch ( error ) {
+            spinner.fail(`Fish completion error: ${ error }.`);
+        }
+    }
+
+    protected async commandAction(options: { shell: 'bash' | 'zsh' | 'fish', file: string, force: boolean }): Promise<void> {
+        switch ( options.shell ) {
+            case 'bash':
+                this.bash();
+                break;
+            case 'zsh':
+                this.zsh();
+                break;
+            case 'fish':
+                await this.fish(options);
+                break;
+            default:
+                console.error('Unsupported shell.');
+                break;
+        }
+    }
+}
+
+
+export default new CompletionCreateUpdateCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/completion/subcommands/CompletionFishCommand.ts b/NodeApp/src/commander/completion/subcommands/CompletionFishCommand.ts
deleted file mode 100644
index 2be5716ee17ae7347d146533f48c8594801b73e5..0000000000000000000000000000000000000000
--- a/NodeApp/src/commander/completion/subcommands/CompletionFishCommand.ts
+++ /dev/null
@@ -1,70 +0,0 @@
-import { generateFishCompletion, getRoot, tryRenameFile } from '../../../helpers/AutoCompletionHelper';
-import CommanderCommand                                   from '../../CommanderCommand';
-import ora                                                from 'ora';
-import TextStyle                                          from '../../../types/TextStyle';
-import path                                               from 'path';
-import os                                                 from 'os';
-import fs                                                 from 'fs-extra';
-import GlobalHelper                                       from '../../../helpers/GlobalHelper';
-
-
-class CompletionFishCommand extends CommanderCommand {
-    protected commandName: string = 'fish';
-
-    private readonly installPath = path.join(os.homedir(), '.config/fish/completions/dojo.fish');
-
-    protected defineCommand() {
-        GlobalHelper.completionCommandDefinition(this.command)
-            .description('generate fish completion')
-            .action(this.commandAction.bind(this));
-    }
-
-    private writeFile(filename: string, showInstructions: boolean) {
-        const spinner: ora.Ora = ora(`Writing fish completion in ${ filename }...`).start();
-
-        try {
-            fs.mkdirsSync(path.dirname(filename));
-
-            fs.writeFileSync(filename, generateFishCompletion(getRoot(this.command)));
-
-            spinner.succeed(`Fish completion successfully written in ${ filename }.`);
-            if ( showInstructions ) {
-                const cpCommand = ` cp -i ${ filename } ~/.config/fish/completions  # interactive cp to avoid accidents `;
-                console.log(`
-The easiest way to install the completion is to copy the ${ TextStyle.CODE(filename) } into the ${ TextStyle.CODE('~/.config/fish/completions') } directory.
-
-${ TextStyle.CODE(cpCommand) }`);
-            }
-        } catch ( error ) {
-            spinner.fail(`Fish completion error: ${ error }.`);
-        }
-    }
-
-
-    /* The completion command must do the following:
-       - if a file is provided:
-            - if force is not enabled:
-                - check if the file exists:
-                    - if it exists, prompt the user that it will be erased
-                        - if ok is given write the file and prompt that a backup has been created
-            - else create the file containing the completion
-        - else
-            - if force is not enabled:
-                - check if the default file exists:
-                    - if it exists, prompt the user that it will be erased:
-                        - if ok is given write the file and prompt that a backup has been created
-            - else
-                - create the file containing the completion
-    */
-    protected async commandAction(options: { file: string, force: boolean }): Promise<void> {
-        const filePath = path.resolve(options.file ?? this.installPath); // change that if file is empty
-        const showInstructions = !!options.file;
-        if ( !(await tryRenameFile(filePath, options.force)) ) { // means renaming was interrupted
-            return;
-        }
-        this.writeFile(filePath, showInstructions);
-    }
-}
-
-
-export default new CompletionFishCommand();
\ No newline at end of file
diff --git a/NodeApp/src/commander/completion/subcommands/CompletionZshCommand.ts b/NodeApp/src/commander/completion/subcommands/CompletionZshCommand.ts
deleted file mode 100644
index 94fe5b44e46293594529c73c38a1459d7ac4d544..0000000000000000000000000000000000000000
--- a/NodeApp/src/commander/completion/subcommands/CompletionZshCommand.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import CommanderCommand from '../../CommanderCommand';
-import path             from 'path';
-import { homedir }      from 'os';
-import { updateRcFile } from '../../../helpers/AutoCompletionHelper';
-
-
-class CompletionZshCommand extends CommanderCommand {
-    protected commandName: string = 'zsh';
-
-    private readonly zshrcPath: string = path.join(homedir(), '.zshrc');
-    private readonly completionCommand = `
-# Added by DojoCLI
-source <(dojo completion script zsh)
-`;
-
-
-    protected defineCommand() {
-        this.command.description('generate zsh completion')
-            .action(this.commandAction.bind(this));
-    }
-
-    protected async commandAction(): Promise<void> {
-        updateRcFile('zsh', this.zshrcPath, this.completionCommand);
-    }
-}
-
-
-export default new CompletionZshCommand();
\ No newline at end of file
diff --git a/NodeApp/src/helpers/GlobalHelper.ts b/NodeApp/src/helpers/GlobalHelper.ts
index 7f0991cbd6ce17a58c1a7845057a2800f99cd7d4..c7dccb10389fda604b31052c01e9fe1e8e54b0cf 100644
--- a/NodeApp/src/helpers/GlobalHelper.ts
+++ b/NodeApp/src/helpers/GlobalHelper.ts
@@ -5,18 +5,10 @@ import Config              from '../config/Config';
 class GlobalHelper {
     public runCommandDefinition(command: Command) {
         command
-        .option('-p, --path <value>', 'assignment path', Config.folders.defaultLocalExercise)
-        .option('-v, --verbose', 'verbose mode - display principal container output in live')
-        .addOption(new Option('-w, --super-verbose', 'verbose mode - display all docker compose logs (build included) in live').conflicts('verbose'))
-        .addOption(new Option('--verbose-ssj2').hideHelp().implies({ superVerbose: true }));
-
-        return command;
-    }
-
-    public completionCommandDefinition(command: Command) {
-        command
-        .option('-f, --file <filename>')
-        .option('-y, --force', 'don\'t ask for file overwrite confirmation');
+            .option('-p, --path <value>', 'assignment path', Config.folders.defaultLocalExercise)
+            .option('-v, --verbose', 'verbose mode - display principal container output in live')
+            .addOption(new Option('-w, --super-verbose', 'verbose mode - display all docker compose logs (build included) in live').conflicts('verbose'))
+            .addOption(new Option('--verbose-ssj2').hideHelp().implies({ superVerbose: true }));
 
         return command;
     }