diff --git a/cmd/flux/delete_helmrelease.go b/cmd/flux/delete_helmrelease.go
index a527b6c2964d2e453cb1b77794cf907e75da7606..ee37b5eee71dfb7b21874fb91f7e85a29575ddb5 100644
--- a/cmd/flux/delete_helmrelease.go
+++ b/cmd/flux/delete_helmrelease.go
@@ -17,15 +17,8 @@ limitations under the License.
 package main
 
 import (
-	"context"
-	"fmt"
-
-	"github.com/manifoldco/promptui"
-	"github.com/spf13/cobra"
-	"k8s.io/apimachinery/pkg/types"
-
-	"github.com/fluxcd/flux2/internal/utils"
 	helmv2 "github.com/fluxcd/helm-controller/api/v2beta1"
+	"github.com/spf13/cobra"
 )
 
 var deleteHelmReleaseCmd = &cobra.Command{
@@ -36,57 +29,12 @@ var deleteHelmReleaseCmd = &cobra.Command{
 	Example: `  # Delete a Helm release and the Kubernetes resources created by it
   flux delete hr podinfo
 `,
-	RunE: deleteHelmReleaseCmdRun,
+	RunE: deleteCommand{
+		apiType: helmReleaseType,
+		object:  universalAdapter{&helmv2.HelmRelease{}},
+	}.run,
 }
 
 func init() {
 	deleteCmd.AddCommand(deleteHelmReleaseCmd)
 }
-
-func deleteHelmReleaseCmdRun(cmd *cobra.Command, args []string) error {
-	if len(args) < 1 {
-		return fmt.Errorf("release name is required")
-	}
-	name := args[0]
-
-	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
-	defer cancel()
-
-	kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
-	if err != nil {
-		return err
-	}
-
-	namespacedName := types.NamespacedName{
-		Namespace: rootArgs.namespace,
-		Name:      name,
-	}
-
-	var helmRelease helmv2.HelmRelease
-	err = kubeClient.Get(ctx, namespacedName, &helmRelease)
-	if err != nil {
-		return err
-	}
-
-	if !deleteArgs.silent {
-		if !helmRelease.Spec.Suspend {
-			logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s Helm release!", name)
-		}
-		prompt := promptui.Prompt{
-			Label:     "Are you sure you want to delete this Helm release",
-			IsConfirm: true,
-		}
-		if _, err := prompt.Run(); err != nil {
-			return fmt.Errorf("aborting")
-		}
-	}
-
-	logger.Actionf("deleting release %s in %s namespace", name, rootArgs.namespace)
-	err = kubeClient.Delete(ctx, &helmRelease)
-	if err != nil {
-		return err
-	}
-	logger.Successf("release deleted")
-
-	return nil
-}
diff --git a/cmd/flux/delete_kustomization.go b/cmd/flux/delete_kustomization.go
index 06a407cf99926fbfce2b1fed9f53f4edf8216b1f..7e1ee3a56fdd3b3cecf6d5f8894a5d0e51c82e0e 100644
--- a/cmd/flux/delete_kustomization.go
+++ b/cmd/flux/delete_kustomization.go
@@ -17,14 +17,8 @@ limitations under the License.
 package main
 
 import (
-	"context"
-	"fmt"
-
-	"github.com/fluxcd/flux2/internal/utils"
 	kustomizev1 "github.com/fluxcd/kustomize-controller/api/v1beta1"
-	"github.com/manifoldco/promptui"
 	"github.com/spf13/cobra"
-	"k8s.io/apimachinery/pkg/types"
 )
 
 var deleteKsCmd = &cobra.Command{
@@ -35,57 +29,12 @@ var deleteKsCmd = &cobra.Command{
 	Example: `  # Delete a kustomization and the Kubernetes resources created by it
   flux delete kustomization podinfo
 `,
-	RunE: deleteKsCmdRun,
+	RunE: deleteCommand{
+		apiType: kustomizationType,
+		object:  universalAdapter{&kustomizev1.Kustomization{}},
+	}.run,
 }
 
 func init() {
 	deleteCmd.AddCommand(deleteKsCmd)
 }
-
-func deleteKsCmdRun(cmd *cobra.Command, args []string) error {
-	if len(args) < 1 {
-		return fmt.Errorf("kustomization name is required")
-	}
-	name := args[0]
-
-	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
-	defer cancel()
-
-	kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
-	if err != nil {
-		return err
-	}
-
-	namespacedName := types.NamespacedName{
-		Namespace: rootArgs.namespace,
-		Name:      name,
-	}
-
-	var kustomization kustomizev1.Kustomization
-	err = kubeClient.Get(ctx, namespacedName, &kustomization)
-	if err != nil {
-		return err
-	}
-
-	if !deleteArgs.silent {
-		if !kustomization.Spec.Suspend {
-			logger.Waitingf("This action will remove the Kubernetes objects previously applied by the %s kustomization!", name)
-		}
-		prompt := promptui.Prompt{
-			Label:     "Are you sure you want to delete this kustomization",
-			IsConfirm: true,
-		}
-		if _, err := prompt.Run(); err != nil {
-			return fmt.Errorf("aborting")
-		}
-	}
-
-	logger.Actionf("deleting kustomization %s in %s namespace", name, rootArgs.namespace)
-	err = kubeClient.Delete(ctx, &kustomization)
-	if err != nil {
-		return err
-	}
-	logger.Successf("kustomization deleted")
-
-	return nil
-}
diff --git a/cmd/flux/delete_source_bucket.go b/cmd/flux/delete_source_bucket.go
index 09130e4ff099dae22092d5693b4ce0209001be4c..ee1bdd2402a137bb154d81f3811f761c3c97fd14 100644
--- a/cmd/flux/delete_source_bucket.go
+++ b/cmd/flux/delete_source_bucket.go
@@ -17,14 +17,8 @@ limitations under the License.
 package main
 
 import (
-	"context"
-	"fmt"
-
-	"github.com/fluxcd/flux2/internal/utils"
 	sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
-	"github.com/manifoldco/promptui"
 	"github.com/spf13/cobra"
-	"k8s.io/apimachinery/pkg/types"
 )
 
 var deleteSourceBucketCmd = &cobra.Command{
@@ -34,54 +28,12 @@ var deleteSourceBucketCmd = &cobra.Command{
 	Example: `  # Delete a Bucket source
   flux delete source bucket podinfo
 `,
-	RunE: deleteSourceBucketCmdRun,
+	RunE: deleteCommand{
+		apiType: bucketType,
+		object:  universalAdapter{&sourcev1.Bucket{}},
+	}.run,
 }
 
 func init() {
 	deleteSourceCmd.AddCommand(deleteSourceBucketCmd)
 }
-
-func deleteSourceBucketCmdRun(cmd *cobra.Command, args []string) error {
-	if len(args) < 1 {
-		return fmt.Errorf("name is required")
-	}
-	name := args[0]
-
-	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
-	defer cancel()
-
-	kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
-	if err != nil {
-		return err
-	}
-
-	namespacedName := types.NamespacedName{
-		Namespace: rootArgs.namespace,
-		Name:      name,
-	}
-
-	var bucket sourcev1.Bucket
-	err = kubeClient.Get(ctx, namespacedName, &bucket)
-	if err != nil {
-		return err
-	}
-
-	if !deleteArgs.silent {
-		prompt := promptui.Prompt{
-			Label:     "Are you sure you want to delete this source",
-			IsConfirm: true,
-		}
-		if _, err := prompt.Run(); err != nil {
-			return fmt.Errorf("aborting")
-		}
-	}
-
-	logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace)
-	err = kubeClient.Delete(ctx, &bucket)
-	if err != nil {
-		return err
-	}
-	logger.Successf("source deleted")
-
-	return nil
-}
diff --git a/cmd/flux/delete_source_git.go b/cmd/flux/delete_source_git.go
index 72c918521eec6599f2489d8cf257728783118cca..b7cbb7b876b5aaed73b0a32c26d81d1ac2449ebf 100644
--- a/cmd/flux/delete_source_git.go
+++ b/cmd/flux/delete_source_git.go
@@ -17,14 +17,8 @@ limitations under the License.
 package main
 
 import (
-	"context"
-	"fmt"
-
-	"github.com/fluxcd/flux2/internal/utils"
 	sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
-	"github.com/manifoldco/promptui"
 	"github.com/spf13/cobra"
-	"k8s.io/apimachinery/pkg/types"
 )
 
 var deleteSourceGitCmd = &cobra.Command{
@@ -34,54 +28,12 @@ var deleteSourceGitCmd = &cobra.Command{
 	Example: `  # Delete a Git repository
   flux delete source git podinfo
 `,
-	RunE: deleteSourceGitCmdRun,
+	RunE: deleteCommand{
+		apiType: gitRepositoryType,
+		object:  universalAdapter{&sourcev1.GitRepository{}},
+	}.run,
 }
 
 func init() {
 	deleteSourceCmd.AddCommand(deleteSourceGitCmd)
 }
-
-func deleteSourceGitCmdRun(cmd *cobra.Command, args []string) error {
-	if len(args) < 1 {
-		return fmt.Errorf("git name is required")
-	}
-	name := args[0]
-
-	ctx, cancel := context.WithTimeout(context.Background(), rootArgs.timeout)
-	defer cancel()
-
-	kubeClient, err := utils.KubeClient(rootArgs.kubeconfig, rootArgs.kubecontext)
-	if err != nil {
-		return err
-	}
-
-	namespacedName := types.NamespacedName{
-		Namespace: rootArgs.namespace,
-		Name:      name,
-	}
-
-	var git sourcev1.GitRepository
-	err = kubeClient.Get(ctx, namespacedName, &git)
-	if err != nil {
-		return err
-	}
-
-	if !deleteArgs.silent {
-		prompt := promptui.Prompt{
-			Label:     "Are you sure you want to delete this source",
-			IsConfirm: true,
-		}
-		if _, err := prompt.Run(); err != nil {
-			return fmt.Errorf("aborting")
-		}
-	}
-
-	logger.Actionf("deleting source %s in %s namespace", name, rootArgs.namespace)
-	err = kubeClient.Delete(ctx, &git)
-	if err != nil {
-		return err
-	}
-	logger.Successf("source deleted")
-
-	return nil
-}
diff --git a/cmd/flux/delete_source_helm.go b/cmd/flux/delete_source_helm.go
index 20b48b467523a5b4399fba048a69d8ae2621e8af..cbe3f86c30e8092ebdc11b4d3faeb7b8ded4edcb 100644
--- a/cmd/flux/delete_source_helm.go
+++ b/cmd/flux/delete_source_helm.go
@@ -34,7 +34,10 @@ var deleteSourceHelmCmd = &cobra.Command{
 	Example: `  # Delete a Helm repository
   flux delete source helm podinfo
 `,
-	RunE: deleteSourceHelmCmdRun,
+	RunE: deleteCommand{
+		apiType: helmRepositoryType,
+		object:  universalAdapter{&sourcev1.HelmRepository{}},
+	}.run,
 }
 
 func init() {