diff --git a/arduino-ide-extension/src/browser/create/create-fs-provider.ts b/arduino-ide-extension/src/browser/create/create-fs-provider.ts
index 7908d0556..db1d7b0f3 100644
--- a/arduino-ide-extension/src/browser/create/create-fs-provider.ts
+++ b/arduino-ide-extension/src/browser/create/create-fs-provider.ts
@@ -1,35 +1,36 @@
-import { inject, injectable } from '@theia/core/shared/inversify';
-import URI from '@theia/core/lib/common/uri';
-import { Event } from '@theia/core/lib/common/event';
+import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
 import {
   Disposable,
   DisposableCollection,
 } from '@theia/core/lib/common/disposable';
-import { FrontendApplicationContribution } from '@theia/core/lib/browser/frontend-application';
+import { Event } from '@theia/core/lib/common/event';
+import URI from '@theia/core/lib/common/uri';
+import { inject, injectable } from '@theia/core/shared/inversify';
+import {
+  FileService,
+  FileServiceContribution,
+} from '@theia/filesystem/lib/browser/file-service';
 import {
-  Stat,
-  FileType,
   FileChange,
-  FileWriteOptions,
   FileDeleteOptions,
   FileOverwriteOptions,
   FileSystemProvider,
+  FileSystemProviderCapabilities,
   FileSystemProviderError,
   FileSystemProviderErrorCode,
-  FileSystemProviderCapabilities,
+  FileType,
+  FileWriteOptions,
+  Stat,
   WatchOptions,
+  createFileSystemProviderError,
 } from '@theia/filesystem/lib/common/files';
-import {
-  FileService,
-  FileServiceContribution,
-} from '@theia/filesystem/lib/browser/file-service';
+import { SketchesService } from '../../common/protocol';
+import { stringToUint8Array } from '../../common/utils';
+import { ArduinoPreferences } from '../arduino-preferences';
 import { AuthenticationClientService } from '../auth/authentication-client-service';
 import { CreateApi } from './create-api';
 import { CreateUri } from './create-uri';
-import { SketchesService } from '../../common/protocol';
-import { ArduinoPreferences } from '../arduino-preferences';
-import { Create } from './typings';
-import { stringToUint8Array } from '../../common/utils';
+import { Create, isNotFound } from './typings';
 
 @injectable()
 export class CreateFsProvider
@@ -90,14 +91,27 @@ export class CreateFsProvider
         size: 0,
       };
     }
-    const resource = await this.getCreateApi.stat(uri.path.toString());
-    const mtime = Date.parse(resource.modified_at);
-    return {
-      type: this.toFileType(resource.type),
-      ctime: mtime,
-      mtime,
-      size: 0,
-    };
+    try {
+      const resource = await this.getCreateApi.stat(uri.path.toString());
+      const mtime = Date.parse(resource.modified_at);
+      return {
+        type: this.toFileType(resource.type),
+        ctime: mtime,
+        mtime,
+        size: 0,
+      };
+    } catch (err) {
+      let errToRethrow = err;
+      // Not Found (Create API) errors must be remapped to VS Code filesystem provider specific errors
+      // https://code.visualstudio.com/api/references/vscode-api#FileSystemError
+      if (isNotFound(errToRethrow)) {
+        errToRethrow = createFileSystemProviderError(
+          errToRethrow,
+          FileSystemProviderErrorCode.FileNotFound
+        );
+      }
+      throw errToRethrow;
+    }
   }
 
   async mkdir(uri: URI): Promise<void> {
diff --git a/arduino-ide-extension/src/browser/theia/workspace/workspace-commands.ts b/arduino-ide-extension/src/browser/theia/workspace/workspace-commands.ts
index ed960356e..f4a608bcd 100644
--- a/arduino-ide-extension/src/browser/theia/workspace/workspace-commands.ts
+++ b/arduino-ide-extension/src/browser/theia/workspace/workspace-commands.ts
@@ -58,6 +58,13 @@ export class WorkspaceCommandContribution extends TheiaWorkspaceCommandContribut
         execute: (uri) => this.newFile(uri),
       })
     );
+    registry.unregisterCommand(WorkspaceCommands.NEW_FOLDER);
+    registry.registerCommand(
+      WorkspaceCommands.NEW_FOLDER,
+      this.newWorkspaceRootUriAwareCommandHandler({
+        execute: (uri) => this.newFolder(uri),
+      })
+    );
     registry.unregisterCommand(WorkspaceCommands.FILE_RENAME);
     registry.registerCommand(
       WorkspaceCommands.FILE_RENAME,
@@ -72,6 +79,37 @@ export class WorkspaceCommandContribution extends TheiaWorkspaceCommandContribut
     );
   }
 
+  private async newFolder(uri: URI | undefined): Promise<void> {
+    if (!uri) {
+      return;
+    }
+
+    const parent = await this.getDirectory(uri);
+    if (!parent) {
+      return;
+    }
+
+    const dialog = new WorkspaceInputDialog(
+      {
+        title: nls.localizeByDefault('New Folder...'),
+        parentUri: uri,
+        placeholder: nls.localize(
+          'theia/workspace/newFolderPlaceholder',
+          'Folder Name'
+        ),
+        validate: (name) => this.validateFileName(name, parent, true),
+      },
+      this.labelProvider
+    );
+    const name = await this.openDialog(dialog, uri);
+    if (!name) {
+      return;
+    }
+    const folderUri = uri.resolve(name);
+    await this.fileService.createFolder(folderUri);
+    this.fireCreateNewFile({ parent: uri, uri: folderUri });
+  }
+
   private async newFile(uri: URI | undefined): Promise<void> {
     if (!uri) {
       return;
diff --git a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts
index 9a5571da2..09b4ced7b 100644
--- a/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts
+++ b/arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts
@@ -389,21 +389,28 @@ export class CloudSketchbookTree extends SketchbookTree {
 
   private async sync(source: URI, dest: URI): Promise<void> {
     const { filesToWrite, filesToDelete } = await this.treeDiff(source, dest);
-    await Promise.all(
-      filesToWrite.map(async ({ source, dest }) => {
-        if ((await this.fileService.resolve(source)).isFile) {
-          const content = await this.fileService.read(source);
-          return this.fileService.write(dest, content.value);
-        }
-        return this.fileService.createFolder(dest);
-      })
+    // Sort by the URIs. The shortest comes first. It's to ensure creating the parent folder for nested resources, for example.
+    // When sorting the URIs, it does not matter whether on source or dest, only the URI path and its length matters; they're the same for a source+dest pair
+    const uriPathLengthComparator = (left: URI, right: URI) =>
+      left.path.toString().length - right.path.toString().length;
+    filesToWrite.sort((left, right) =>
+      uriPathLengthComparator(left.source, right.source)
     );
+    for (const { source, dest } of filesToWrite) {
+      const stat = await this.fileService.resolve(source);
+      if (stat.isFile) {
+        const content = await this.fileService.read(source);
+        await this.fileService.write(dest, content.value);
+      } else {
+        await this.fileService.createFolder(dest);
+      }
+    }
 
-    await Promise.all(
-      filesToDelete.map((file) =>
-        this.fileService.delete(file, { recursive: true })
-      )
-    );
+    // Longes URI paths come first to delete the most nested ones first.
+    filesToDelete.sort(uriPathLengthComparator).reverse();
+    for (const resource of filesToDelete) {
+      await this.fileService.delete(resource, { recursive: true });
+    }
   }
 
   override async resolveChildren(
diff --git a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts
index c8935d663..625cf6fde 100644
--- a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts
+++ b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-commands.ts
@@ -25,6 +25,14 @@ export namespace SketchbookCommands {
     'arduino/sketch/openFolder'
   );
 
+  export const NEW_FOLDER = Command.toLocalizedCommand(
+    {
+      id: 'arduino-sketchbook--new-folder',
+      label: 'New Folder',
+    },
+    'arduino/sketch/newFolder'
+  );
+
   export const OPEN_SKETCHBOOK_CONTEXT_MENU: Command = {
     id: 'arduino-sketchbook--open-sketch-context-menu',
     iconClass: 'sketchbook-tree__opts',
diff --git a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts
index e73bb7e2f..0c368f7e7 100644
--- a/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts
+++ b/arduino-ide-extension/src/browser/widgets/sketchbook/sketchbook-widget-contribution.ts
@@ -28,7 +28,10 @@ import {
 } from '../../sketches-service-client-impl';
 import { FileService } from '@theia/filesystem/lib/browser/file-service';
 import { URI } from '../../contributions/contribution';
-import { WorkspaceInput } from '@theia/workspace/lib/browser';
+import {
+  WorkspaceCommands,
+  WorkspaceInput,
+} from '@theia/workspace/lib/browser';
 
 export const SKETCHBOOK__CONTEXT = ['arduino-sketchbook--context'];
 
@@ -130,6 +133,21 @@ export class SketchbookWidgetContribution
         !!arg && 'node' in arg && SketchbookTree.SketchDirNode.is(arg.node),
     });
 
+    registry.registerCommand(SketchbookCommands.NEW_FOLDER, {
+      execute: async (arg) => {
+        if (arg.node.uri) {
+          return registry.executeCommand(
+            WorkspaceCommands.NEW_FOLDER.id,
+            arg.node.uri
+          );
+        }
+      },
+      isEnabled: (arg) =>
+        !!arg && 'node' in arg && SketchbookTree.SketchDirNode.is(arg.node),
+      isVisible: (arg) =>
+        !!arg && 'node' in arg && SketchbookTree.SketchDirNode.is(arg.node),
+    });
+
     registry.registerCommand(SketchbookCommands.OPEN_SKETCHBOOK_CONTEXT_MENU, {
       isEnabled: (arg) =>
         !!arg && 'node' in arg && SketchbookTree.SketchDirNode.is(arg.node),
@@ -206,6 +224,12 @@ export class SketchbookWidgetContribution
       label: SketchbookCommands.REVEAL_IN_FINDER.label,
       order: '0',
     });
+
+    registry.registerMenuAction(SKETCHBOOK__CONTEXT__MAIN_GROUP, {
+      commandId: SketchbookCommands.NEW_FOLDER.id,
+      label: SketchbookCommands.NEW_FOLDER.label,
+      order: '1',
+    });
   }
 
   private openNewWindow(
diff --git a/i18n/en.json b/i18n/en.json
index c83d280c1..800569d43 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -455,6 +455,7 @@
       "moving": "Moving",
       "movingMsg": "The file \"{0}\" needs to be inside a sketch folder named \"{1}\".\nCreate this folder, move the file, and continue?",
       "new": "New Sketch",
+      "newFolder": "New Folder",
       "noTrailingPeriod": "A filename cannot end with a dot",
       "openFolder": "Open Folder",
       "openRecent": "Open Recent",
@@ -545,7 +546,8 @@
       "deleteCurrentSketch": "The sketch '{0}' will be permanently deleted. This action is irreversible. Do you want to delete the current sketch?",
       "fileNewName": "Name for new file",
       "invalidExtension": ".{0} is not a valid extension",
-      "newFileName": "New name for file"
+      "newFileName": "New name for file",
+      "newFolderPlaceholder": "Folder Name"
     }
   }
 }