diff --git a/Cargo.lock b/Cargo.lock
index 419f0950739..22c5cba1e72 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -546,6 +546,7 @@ dependencies = [
  "git-features",
  "gitoxide-core",
  "prodash",
+ "smol",
  "structopt",
 ]
 
@@ -848,9 +849,9 @@ dependencies = [
 
 [[package]]
 name = "prodash"
-version = "4.0.4"
+version = "4.0.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34cdc02202ba329a65f1f5d98acd7a4f653c48378713526e7a20345479ae6dfa"
+checksum = "2db0f9242151525bdf735374355312312d0cf334328fd2b8f290c8eb8842ccd2"
 dependencies = [
  "dashmap",
  "futures-channel",
diff --git a/Cargo.toml b/Cargo.toml
index d315d48ffc4..50c73106c42 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -28,7 +28,8 @@ pretty-cli = ["structopt",
               "prodash/log-renderer",
               "prodash/tui-renderer",
               "prodash/localtime",
-              "env_logger"]
+              "env_logger",
+              "smol"]
 lean-cli = ["argh", "git-features/progress-log", "env_logger"]
 
 [dependencies]
@@ -39,7 +40,8 @@ git-features = { version = "0.1.0", path = "git-features" }
 
 structopt = { version = "0.3.14", optional = true }
 argh = { version = "0.1.3", optional = true }
-prodash = { version = "4.0.4", optional = true, default-features = false }
+prodash = { version = "4.0.5", optional = true, default-features = false }
+smol = { version = "0.1.18", optional = true }
 env_logger = { version = "0.7.1", optional = true, default-features = false, features = ["humantime", "termcolor", "atty"] }
 
 [profile.release]
diff --git a/git-features/Cargo.toml b/git-features/Cargo.toml
index 83bd6a99e42..f44ef899f19 100644
--- a/git-features/Cargo.toml
+++ b/git-features/Cargo.toml
@@ -32,4 +32,4 @@ fastsha1 = { package = "sha-1", version = "0.9.1", optional = true }
 
 # progress
 log = { version = "0.4.8", optional = true }
-prodash = { version = "4.0.4", optional = true, default-features = false }
+prodash = { version = "4.0.5", optional = true, default-features = false }
diff --git a/src/plumbing/pretty.rs b/src/plumbing/pretty.rs
index 13cb7571e42..352ed408eb7 100644
--- a/src/plumbing/pretty.rs
+++ b/src/plumbing/pretty.rs
@@ -25,6 +25,11 @@ mod options {
             /// if set, verbose progress messages are printed line by line
             #[structopt(long, short = "v")]
             verbose: bool,
+
+            /// if set, bring up a terminal user interface displaying progress visually
+            #[structopt(long, conflicts_with("verbose"))]
+            progress: bool,
+
             /// The '.pack' or '.idx' file whose checksum to validate.
             #[structopt(parse(from_os_str))]
             path: PathBuf,
@@ -32,25 +37,46 @@ mod options {
     }
 }
 
-fn init_progress(name: &str, verbose: bool) -> progress::DoOrDiscard<progress::Log> {
+fn init_progress(
+    name: &str,
+    verbose: bool,
+    progress: bool,
+) -> Option<progress::Either<progress::Log, prodash::tree::Item>> {
     super::init_env_logger(verbose);
-    progress::DoOrDiscard::from(if verbose {
-        Some(progress::Log::new(name))
-    } else {
-        None
-    })
+    match (verbose, progress) {
+        (false, false) => None,
+        (true, false) => Some(progress::Either::Left(progress::Log::new(name))),
+        (true, true) | (false, true) => {
+            let progress = prodash::Tree::new();
+            let sub_progress = progress.add_child(name);
+            let render_tui = prodash::tui::render(
+                progress,
+                prodash::tui::TuiOptions {
+                    title: "gitoxide".into(),
+                    frames_per_second: 6.0,
+                    ..Default::default()
+                },
+            )
+            .expect("tui to come up without io error");
+            std::thread::spawn(move || smol::run(render_tui));
+
+            Some(progress::Either::Right(sub_progress))
+        }
+    }
 }
 
 pub fn main() -> Result<()> {
     use options::*;
     let args = Args::from_args();
     match args.cmd {
-        Subcommands::VerifyPack { path, verbose } => core::verify_pack_or_pack_index(
+        Subcommands::VerifyPack {
             path,
-            init_progress("verify-pack", verbose).into(),
-            stdout(),
-            stderr(),
-        ),
+            verbose,
+            progress,
+        } => {
+            let progress = init_progress("verify-pack", verbose, progress);
+            core::verify_pack_or_pack_index(path, progress, stdout(), stderr())
+        }
     }?;
     Ok(())
 }
diff --git a/tasks.md b/tasks.md
index e2da366ebc6..ffb8838f8f1 100644
--- a/tasks.md
+++ b/tasks.md
@@ -26,9 +26,7 @@
    * [x] validate index and pack
    * **progress**
      * [x] for `lean` binary behind --verbose flag
-     * [ ] for `pretty` binary with support for
-       * [x] logging
-       * [ ] TUI
+     * [x] for `pretty` binary with support for logging and TUI
    * [ ] statistics
    * [ ] a verbose mode to list each object in a pack, similar to existing git-verify-pack
 * **stress**