diff --git a/src/vm.zig b/src/vm.zig
index 1f1ac35..ae0d894 100644
--- a/src/vm.zig
+++ b/src/vm.zig
@@ -46,29 +46,48 @@ pub fn detectProjectVersion(allocator: mem.Allocator, is_debug: bool) !?[]const
         // ToolVersionsFile.init(),
     };
 
-    for (files) |version_file| {
-        const file = fs.cwd().openFile(version_file.name, .{}) catch |err| switch (err) {
-            error.FileNotFound => continue,
-            else => |e| return e,
-        };
-        defer file.close();
-
-        const file_size = try file.getEndPos();
-        const buffer = try std.heap.page_allocator.alloc(u8, file_size);
-        defer std.heap.page_allocator.free(buffer);
+    var current_dir = try fs.cwd().realpathAlloc(allocator, ".");
+    defer allocator.free(current_dir);
+
+    while (true) {
+        if (is_debug) std.debug.print("Checking dir: {s}\n", .{current_dir});
+        for (files) |version_file| {
+            const file_path = try fs.path.join(allocator, &[_][]const u8{ current_dir, version_file.name });
+            defer allocator.free(file_path);
+
+            const file = fs.openFileAbsolute(file_path, .{}) catch |err| switch (err) {
+                error.FileNotFound => continue,
+                else => |e| return e,
+            };
+            defer file.close();
+
+            const file_size = try file.getEndPos();
+            const buffer = try allocator.alloc(u8, file_size);
+            defer allocator.free(buffer);
+
+            _ = try file.readAll(buffer);
+            if (version_file.extractBunVersion(allocator, buffer)) |version| {
+                if (is_debug) std.debug.print("Found v{s} in {s}\n", .{ version, file_path });
+                return try allocator.dupe(u8, version);
+            }
+        }
 
-        _ = try file.readAll(buffer);
-        if (version_file.extractBunVersion(allocator, buffer)) |version| {
-            if (is_debug) std.debug.print("Found v{s} in {s}\n", .{ version, version_file.name });
-            return try allocator.dupe(u8, version);
+        // Move up to the parent directory
+        const parent_dir = fs.path.dirname(current_dir);
+        if (parent_dir == null or mem.eql(u8, parent_dir.?, current_dir)) {
+            // We've reached the root directory, stop searching
+            break;
         }
+        const new_dir = try fs.path.join(allocator, &[_][]const u8{parent_dir.?});
+        allocator.free(current_dir);
+        current_dir = new_dir;
     }
 
-    return error.NoBunVersionFound;
+    return null;
 }
 
 pub fn getLatestLocalVersion(allocator: mem.Allocator, is_debug: bool, config_dir: []const u8) !?[]const u8 {
-    if (is_debug) std.debug.print("Getting latest local verison...", .{});
+    if (is_debug) std.debug.print("Getting latest local verison...\n", .{});
 
     const installed_versions = try getInstalledVersions(allocator, config_dir);
     defer {
@@ -78,14 +97,14 @@ pub fn getLatestLocalVersion(allocator: mem.Allocator, is_debug: bool, config_di
         installed_versions.deinit();
     }
 
-    if (installed_versions.items.len == 1) {
+    if (installed_versions.items.len != 1) {
         return null;
     }
     return try allocator.dupe(u8, installed_versions.items[0]);
 }
 
 pub fn getLatestRemoteVersion(_: mem.Allocator, is_debug: bool) ![]u8 {
-    if (is_debug) std.debug.print("Getting latest remote verison...", .{});
+    if (is_debug) std.debug.print("Getting latest remote verison...\n", .{});
     return error.Todo;
 }
 
@@ -194,8 +213,10 @@ const PackageJsonVersionFile = struct {
         defer parsed.deinit();
 
         // "bun@X.Y.Z"
-        const package_manager = parsed.value.object.get("packageManager").?.string;
-        return allocator.dupe(u8, package_manager[4..]) catch return null;
+        if (parsed.value.object.get("packageManager")) |package_manager| {
+            return allocator.dupe(u8, package_manager.string[4..]) catch return null;
+        }
+        return null;
     }
 };