diff --git a/cmd/flux/bootstrap.go b/cmd/flux/bootstrap.go
index c0d8d4deb12161fdade0eae6e2457e5471921b0c..390a0f997aecc5064278c622ec717b5a6a7a9279 100644
--- a/cmd/flux/bootstrap.go
+++ b/cmd/flux/bootstrap.go
@@ -47,7 +47,8 @@ var bootstrapCmd = &cobra.Command{
 
 var (
 	bootstrapVersion            string
-	bootstrapComponents         []string
+	bootstrapDefaultComponents  []string
+	bootstrapExtraComponents    []string
 	bootstrapRegistry           string
 	bootstrapImagePullSecret    string
 	bootstrapBranch             string
@@ -67,8 +68,10 @@ const (
 func init() {
 	bootstrapCmd.PersistentFlags().StringVarP(&bootstrapVersion, "version", "v", defaults.Version,
 		"toolkit version")
-	bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapComponents, "components", defaults.Components,
+	bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapDefaultComponents, "components", defaults.Components,
 		"list of components, accepts comma-separated values")
+	bootstrapCmd.PersistentFlags().StringSliceVar(&bootstrapExtraComponents, "components-extra", nil,
+		"list of components in addition to those supplied or defaulted, accepts comma-separated values")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapRegistry, "registry", "ghcr.io/fluxcd",
 		"container registry where the toolkit images are published")
 	bootstrapCmd.PersistentFlags().StringVar(&bootstrapImagePullSecret, "image-pull-secret", "",
@@ -88,13 +91,17 @@ func init() {
 	rootCmd.AddCommand(bootstrapCmd)
 }
 
+func bootstrapComponents() []string {
+	return append(bootstrapDefaultComponents, bootstrapExtraComponents...)
+}
+
 func bootstrapValidate() error {
+	components := bootstrapComponents()
 	for _, component := range bootstrapRequiredComponents {
-		if !utils.ContainsItemString(bootstrapComponents, component) {
+		if !utils.ContainsItemString(components, component) {
 			return fmt.Errorf("component %s is required", component)
 		}
 	}
-
 	return nil
 }
 
@@ -103,7 +110,7 @@ func generateInstallManifests(targetPath, namespace, tmpDir string, localManifes
 		BaseURL:                localManifests,
 		Version:                bootstrapVersion,
 		Namespace:              namespace,
-		Components:             bootstrapComponents,
+		Components:             bootstrapComponents(),
 		Registry:               bootstrapRegistry,
 		ImagePullSecret:        bootstrapImagePullSecret,
 		Arch:                   bootstrapArch.String(),
diff --git a/cmd/flux/bootstrap_github.go b/cmd/flux/bootstrap_github.go
index a17837d4df7b263858b10a964aa68783ccf73972..e8c21606f42fe9c21d6f44d56a6795100902393b 100644
--- a/cmd/flux/bootstrap_github.go
+++ b/cmd/flux/bootstrap_github.go
@@ -206,7 +206,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
 	if isInstall {
 		// apply install manifests
 		logger.Actionf("installing components in %s namespace", namespace)
-		if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
+		if err := applyInstallManifests(ctx, manifest, bootstrapComponents()); err != nil {
 			return err
 		}
 		logger.Successf("install completed")
diff --git a/cmd/flux/bootstrap_gitlab.go b/cmd/flux/bootstrap_gitlab.go
index 546d93fb0be68e8833022501a83e510179bde0ad..1d8c6884b97ae105bef8ffe11c1ce449f986c5ec 100644
--- a/cmd/flux/bootstrap_gitlab.go
+++ b/cmd/flux/bootstrap_gitlab.go
@@ -172,7 +172,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
 	if isInstall {
 		// apply install manifests
 		logger.Actionf("installing components in %s namespace", namespace)
-		if err := applyInstallManifests(ctx, manifest, bootstrapComponents); err != nil {
+		if err := applyInstallManifests(ctx, manifest, bootstrapComponents()); err != nil {
 			return err
 		}
 		logger.Successf("install completed")
diff --git a/cmd/flux/install.go b/cmd/flux/install.go
index 3bcd6911286f2db0c4c871e83c3c4c622eccbde4..7496722f0228b4064aeebe59b6c3cf147ad8c1d6 100644
--- a/cmd/flux/install.go
+++ b/cmd/flux/install.go
@@ -56,7 +56,7 @@ var (
 	installDryRun             bool
 	installManifestsPath      string
 	installVersion            string
-	installComponents         []string
+	installDefaultComponents  []string
 	installExtraComponents    []string
 	installRegistry           string
 	installImagePullSecret    string
@@ -73,9 +73,9 @@ func init() {
 		"only print the object that would be applied")
 	installCmd.Flags().StringVarP(&installVersion, "version", "v", defaults.Version,
 		"toolkit version")
-	installCmd.Flags().StringSliceVar(&installComponents, "components", defaults.Components,
+	installCmd.Flags().StringSliceVar(&installDefaultComponents, "components", defaults.Components,
 		"list of components, accepts comma-separated values")
-	installCmd.Flags().StringSliceVar(&installExtraComponents, "extra-components", nil,
+	installCmd.Flags().StringSliceVar(&installExtraComponents, "components-extra", nil,
 		"list of components in addition to those supplied or defaulted, accepts comma-separated values")
 	installCmd.Flags().StringVar(&installManifestsPath, "manifests", "", "path to the manifest directory")
 	installCmd.Flags().MarkHidden("manifests")
@@ -106,7 +106,7 @@ func installCmdRun(cmd *cobra.Command, args []string) error {
 		logger.Generatef("generating manifests")
 	}
 
-	components := append(installComponents, installExtraComponents...)
+	components := append(installDefaultComponents, installExtraComponents...)
 
 	opts := install.Options{
 		BaseURL:                installManifestsPath,
diff --git a/docs/cmd/flux_bootstrap.md b/docs/cmd/flux_bootstrap.md
index 4d1f20b0f3efdbf5f34588655c8610f1fe5b5a46..19a2abdf084993fa0b74728ba55d5600b0c81242 100644
--- a/docs/cmd/flux_bootstrap.md
+++ b/docs/cmd/flux_bootstrap.md
@@ -12,6 +12,7 @@ The bootstrap sub-commands bootstrap the toolkit components on the targeted Git
       --arch arch                  cluster architecture, available options are: (amd64, arm, arm64) (default amd64)
       --branch string              default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
+      --components-extra strings   list of components in addition to those supplied or defaulted, accepts comma-separated values
   -h, --help                       help for bootstrap
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --log-level logLevel         log level, available options are: (debug, info, error) (default info)
diff --git a/docs/cmd/flux_bootstrap_github.md b/docs/cmd/flux_bootstrap_github.md
index 4186515a7f2bf1062e35498c7c16c95881050548..c34e23422139a90ae44af0c36b8cd16e3019850c 100644
--- a/docs/cmd/flux_bootstrap_github.md
+++ b/docs/cmd/flux_bootstrap_github.md
@@ -64,6 +64,7 @@ flux bootstrap github [flags]
       --arch arch                  cluster architecture, available options are: (amd64, arm, arm64) (default amd64)
       --branch string              default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
+      --components-extra strings   list of components in addition to those supplied or defaulted, accepts comma-separated values
       --context string             kubernetes context to use
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --kubeconfig string          path to the kubeconfig file (default "~/.kube/config")
diff --git a/docs/cmd/flux_bootstrap_gitlab.md b/docs/cmd/flux_bootstrap_gitlab.md
index a4682511c8455945c7da04b4f19fa84e60c60a88..86b391f72a69206b8f8829bb8800ffd25d36f3e2 100644
--- a/docs/cmd/flux_bootstrap_gitlab.md
+++ b/docs/cmd/flux_bootstrap_gitlab.md
@@ -60,6 +60,7 @@ flux bootstrap gitlab [flags]
       --arch arch                  cluster architecture, available options are: (amd64, arm, arm64) (default amd64)
       --branch string              default branch (for GitHub this must match the default branch setting for the organization) (default "main")
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
+      --components-extra strings   list of components in addition to those supplied or defaulted, accepts comma-separated values
       --context string             kubernetes context to use
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --kubeconfig string          path to the kubeconfig file (default "~/.kube/config")
diff --git a/docs/cmd/flux_install.md b/docs/cmd/flux_install.md
index 61bfb00fa6f0fdb0ad43f6d680c8c8bba5315744..f1e8086823c6c33835071af4cfe8b5c2279049c6 100644
--- a/docs/cmd/flux_install.md
+++ b/docs/cmd/flux_install.md
@@ -33,9 +33,9 @@ flux install [flags]
 ```
       --arch arch                  cluster architecture, available options are: (amd64, arm, arm64) (default amd64)
       --components strings         list of components, accepts comma-separated values (default [source-controller,kustomize-controller,helm-controller,notification-controller])
+      --components-extra strings   list of components in addition to those supplied or defaulted, accepts comma-separated values
       --dry-run                    only print the object that would be applied
       --export                     write the install manifests to stdout and exit
-      --extra-components strings   list of components in addition to those supplied or defaulted, accepts comma-separated values
   -h, --help                       help for install
       --image-pull-secret string   Kubernetes secret name used for pulling the toolkit images from a private registry
       --log-level logLevel         log level, available options are: (debug, info, error) (default info)