diff --git a/src/components/BucketView.vue b/src/components/BucketView.vue
index ba226f289d7650b90af4539a1b1184b73adf2a35..72211963814354bad2a02d41ec129c080d3ed218 100644
--- a/src/components/BucketView.vue
+++ b/src/components/BucketView.vue
@@ -10,6 +10,7 @@ import { Tooltip } from "bootstrap";
 import PermissionListModal from "@/components/Modals/PermissionListModal.vue";
 import UploadObjectModal from "@/components/Modals/UploadObjectModal.vue";
 import PermissionModal from "@/components/Modals/PermissionModal.vue";
+import CreateFolderModal from "@/components/Modals/CreateFolderModal.vue";
 import { S3Client } from "@aws-sdk/client-s3";
 import { awsAuthMiddlewareOptions } from "@aws-sdk/middleware-signing";
 
@@ -203,7 +204,7 @@ const visibleObjects: ComputedRef<(S3ObjectWithFolder | S3PseudoFolder)[]> =
         } as S3PseudoFolder;
       })
     );
-    return arr;
+    return arr.filter((obj) => !obj.key.endsWith(".s3keep"));
   });
 
 const subFolderInUrl: ComputedRef<boolean> = computed(
@@ -390,7 +391,6 @@ watch(
       </button>
       <upload-object-modal
         :bucket-name="props.bucketName"
-        :sub-folders="[]"
         :s3-client="client"
         modalID="upload-object-modal"
         modal-label="some-label"
@@ -402,13 +402,22 @@ watch(
         type="button"
         class="btn btn-secondary m-2 tooltip-container"
         :disabled="errorLoadingObjects"
-        data-bs-toggle="tooltip"
+        data-bs-toggle="modal"
         data-bs-title="Create Folder"
+        data-bs-target="#create-folder-modal"
       >
         <bootstrap-icon icon="plus-lg" :width="16" :height="16" fill="white" />
         Folder
         <span class="visually-hidden">Add Folder</span>
       </button>
+      <create-folder-modal
+        :bucket-name="props.bucketName"
+        :s3-client="client"
+        modalID="create-folder-modal"
+        modal-label="some-label"
+        :key-prefix="currentSubFolders.join('/')"
+        @folder-created="objectUploaded"
+      />
       <!-- Add bucket permission button -->
       <button
         :hidden="props.permission != null"
diff --git a/src/components/Modals/CreateFolderModal.vue b/src/components/Modals/CreateFolderModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..d789c8f9cca8013154acf82e90fc4bea7ec8035c
--- /dev/null
+++ b/src/components/Modals/CreateFolderModal.vue
@@ -0,0 +1,194 @@
+<script setup lang="ts">
+import type { S3Client } from "@aws-sdk/client-s3";
+import { PutObjectCommand } from "@aws-sdk/client-s3";
+import BootstrapModal from "@/components/Modals/BootstrapModal.vue";
+import { computed, onMounted, reactive } from "vue";
+import type { ComputedRef } from "vue";
+import type { S3ObjectMetaInformation } from "@/client";
+import dayjs from "dayjs";
+import { Modal, Toast } from "bootstrap";
+
+const props = defineProps<{
+  modalID: string;
+  modalLabel: string;
+  bucketName: string;
+  keyPrefix: string;
+  s3Client: S3Client;
+}>();
+
+const randomIDSuffix = Math.random().toString(16).substr(2, 8);
+let uploadModal: Modal | null = null;
+let successToast: Toast | null = null;
+let errorToast: Toast | null = null;
+
+const currentFolders: ComputedRef<string[]> = computed(() =>
+  props.keyPrefix.split("/")
+);
+
+const emit = defineEmits<{
+  (e: "folder-created", object: S3ObjectMetaInformation): void;
+}>();
+
+const formState = reactive({
+  folderName: "",
+  uploading: false,
+} as {
+  folderName: string;
+  uploading: boolean;
+});
+
+function uploadFolder() {
+  const key =
+    (props.keyPrefix.length > 0
+      ? props.keyPrefix + "/" + formState.folderName
+      : formState.folderName) + "/.s3keep";
+  const command = new PutObjectCommand({
+    Bucket: props.bucketName,
+    Body: "",
+    ContentType: "text/plain",
+    Key: key,
+  });
+  formState.uploading = true;
+  props.s3Client
+    .send(command)
+    .then(() => {
+      uploadModal?.hide();
+      successToast?.show();
+      emit("folder-created", {
+        key: key,
+        bucket: props.bucketName,
+        size: 0,
+        last_modified: dayjs().toISOString(),
+      });
+      formState.folderName = "";
+    })
+    .catch((e) => {
+      console.error(e);
+      errorToast?.show();
+    })
+    .finally(() => {
+      formState.uploading = false;
+    });
+}
+
+onMounted(() => {
+  uploadModal = new Modal("#" + props.modalID);
+  successToast = new Toast("#successToast-" + randomIDSuffix);
+  errorToast = new Toast("#errorToast-" + randomIDSuffix);
+});
+</script>
+
+<template>
+  <div class="toast-container position-fixed top-0 end-0 p-3">
+    <div
+      role="alert"
+      aria-live="assertive"
+      aria-atomic="true"
+      class="toast text-bg-success align-items-center border-0"
+      data-bs-autohide="true"
+      :id="'successToast-' + randomIDSuffix"
+    >
+      <div class="d-flex">
+        <div class="toast-body">Successfully created Folder</div>
+        <button
+          type="button"
+          class="btn-close btn-close-white me-2 m-auto"
+          data-bs-dismiss="toast"
+          aria-label="Close"
+        ></button>
+      </div>
+    </div>
+  </div>
+  <div class="toast-container position-fixed top-0 end-0 p-3">
+    <div
+      role="alert"
+      aria-live="assertive"
+      aria-atomic="true"
+      class="toast text-bg-danger align-items-center border-0"
+      data-bs-autohide="true"
+      :id="'errorToast-' + randomIDSuffix"
+    >
+      <div class="d-flex">
+        <div class="toast-body">
+          There has been some Error.<br />
+          Try again later
+        </div>
+        <button
+          type="button"
+          class="btn-close btn-close-white me-2 m-auto"
+          data-bs-dismiss="toast"
+          aria-label="Close"
+        ></button>
+      </div>
+    </div>
+  </div>
+  <bootstrap-modal
+    :modalID="modalID"
+    :static-backdrop="true"
+    :modal-label="modalLabel"
+  >
+    <template v-slot:header>
+      <h4>Create folder in</h4>
+      <ol class="breadcrumb">
+        <li class="breadcrumb-item">{{ props.bucketName }}</li>
+        <li
+          class="breadcrumb-item"
+          v-for="folder in currentFolders"
+          :key="folder"
+        >
+          {{ folder }}
+        </li>
+      </ol>
+    </template>
+    <template v-slot:body>
+      <div class="container-fluid">
+        <div class="row">
+          <form
+            class="col-7"
+            :id="'uploadFolderForm' + randomIDSuffix"
+            @submit.prevent="uploadFolder"
+          >
+            <div class="mb-3">
+              <label :for="'folderName' + randomIDSuffix" class="form-label"
+                >Folder Name</label
+              >
+              <input
+                type="text"
+                class="form-control"
+                :id="'folderName' + randomIDSuffix"
+                required
+                v-model="formState.folderName"
+              />
+            </div>
+          </form>
+          <div class="col-5">
+            Note: Delimiters ('/') are allowed in the folder name to place the
+            new folder into a folder that will be created when the folder is
+            created (to any depth of folders).
+          </div>
+        </div>
+      </div>
+    </template>
+    <template v-slot:footer>
+      <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">
+        Close
+      </button>
+      <button
+        :disabled="formState.uploading"
+        type="submit"
+        :form="'uploadFolderForm' + randomIDSuffix"
+        class="btn btn-primary"
+      >
+        <span
+          v-if="formState.uploading"
+          class="spinner-border spinner-border-sm"
+          role="status"
+          aria-hidden="true"
+        ></span>
+        Create
+      </button>
+    </template>
+  </bootstrap-modal>
+</template>
+
+<style scoped></style>
diff --git a/vite.config.ts b/vite.config.ts
index 1efdea2b75099a671e1290beda4addab8689c3b4..5679c45caa3c4a796331cd1a26a97a29d4eea82f 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -27,10 +27,8 @@ export default defineConfig({
       // Enable esbuild polyfill plugins
       plugins: [
         NodeGlobalsPolyfillPlugin({
-          stream: true,
           buffer: true,
           process: true,
-          util: true,
         }),
         NodeModulesPolyfillPlugin(),
       ],