diff --git a/src/drivers.rs b/src/drivers.rs
index 5b053f25..8c5a9724 100644
--- a/src/drivers.rs
+++ b/src/drivers.rs
@@ -10,6 +10,9 @@ use version::find_version;
 
 mod vfs;
 
+mod visitor;
+pub use visitor::*;
+
 /// Fetch a crate by name and version from github
 /// TODO: implement this
 pub async fn fetch_crate_gh_releases(
diff --git a/src/drivers/visitor.rs b/src/drivers/visitor.rs
new file mode 100644
index 00000000..005dbace
--- /dev/null
+++ b/src/drivers/visitor.rs
@@ -0,0 +1,80 @@
+use std::io::Read;
+use std::path::{Path, PathBuf};
+
+use cargo_toml::Manifest;
+use log::debug;
+use tar::Entries;
+
+use super::vfs::Vfs;
+use crate::{
+    helpers::{PathExt, TarEntriesVisitor},
+    BinstallError, Meta,
+};
+
+#[derive(Debug)]
+pub struct ManifestVisitor {
+    cargo_toml_content: Vec<u8>,
+    /// manifest_dir_path is treated as the current dir.
+    manifest_dir_path: PathBuf,
+
+    vfs: Vfs,
+}
+
+impl ManifestVisitor {
+    pub(super) fn new(manifest_dir_path: PathBuf) -> Self {
+        Self {
+            // Cargo.toml is quite large usually.
+            cargo_toml_content: Vec::with_capacity(2000),
+            manifest_dir_path,
+            vfs: Vfs::new(),
+        }
+    }
+
+    /// Load binstall metadata using the extracted information stored in memory.
+    pub fn load_manifest(&self) -> Result<Manifest<Meta>, BinstallError> {
+        debug!("Loading manifest directly from extracted file");
+
+        // Load and parse manifest
+        let mut manifest = Manifest::<Meta>::from_slice_with_metadata(&self.cargo_toml_content)?;
+
+        // Checks vfs for binary output names
+        manifest.complete_from_abstract_filesystem(&self.vfs)?;
+
+        // Return metadata
+        Ok(manifest)
+    }
+}
+
+impl TarEntriesVisitor for ManifestVisitor {
+    fn visit<R: Read>(&mut self, entries: Entries<'_, R>) -> Result<(), BinstallError> {
+        for res in entries {
+            let mut entry = res?;
+            let path = entry.path()?.normalize_path();
+
+            let path = if let Ok(path) = path.strip_prefix(&self.manifest_dir_path) {
+                path
+            } else {
+                // The path is outside of the curr dir (manifest dir),
+                // ignore it.
+                continue;
+            };
+
+            if path == Path::new("Cargo.toml")
+                || path == Path::new("src/main.rs")
+                || path.starts_with("src/bin")
+            {
+                self.vfs.add_path(path);
+            }
+
+            if path == Path::new("Cargo.toml") {
+                // Since it is possible for the same Cargo.toml to appear
+                // multiple times using `tar --keep-old-files`, here we
+                // clear the buffer first before reading into it.
+                self.cargo_toml_content.clear();
+                entry.read_to_end(&mut self.cargo_toml_content)?;
+            }
+        }
+
+        Ok(())
+    }
+}