diff --git a/src/client/app/desktop/views/components/drive.file.vue b/src/client/app/desktop/views/components/drive.file.vue
index a4531e221f..86addb1318 100644
--- a/src/client/app/desktop/views/components/drive.file.vue
+++ b/src/client/app/desktop/views/components/drive.file.vue
@@ -145,7 +145,7 @@ export default Vue.extend({
 				(this as any).api('drive/files/update', {
 					fileId: this.file.id,
 					name: name
-				})
+				});
 			});
 		},
 
@@ -173,7 +173,9 @@ export default Vue.extend({
 		},
 
 		deleteFile() {
-			alert('not implemented yet');
+			(this as any).api('drive/files/delete', {
+				fileId: this.file.id
+			});
 		}
 	}
 });
diff --git a/src/client/app/desktop/views/components/drive.vue b/src/client/app/desktop/views/components/drive.vue
index b69c884089..df141b6d6c 100644
--- a/src/client/app/desktop/views/components/drive.vue
+++ b/src/client/app/desktop/views/components/drive.vue
@@ -118,6 +118,7 @@ export default Vue.extend({
 
 		this.connection.on('file_created', this.onStreamDriveFileCreated);
 		this.connection.on('file_updated', this.onStreamDriveFileUpdated);
+		this.connection.on('file_deleted', this.onStreamDriveFileDeleted);
 		this.connection.on('folder_created', this.onStreamDriveFolderCreated);
 		this.connection.on('folder_updated', this.onStreamDriveFolderUpdated);
 
@@ -130,6 +131,7 @@ export default Vue.extend({
 	beforeDestroy() {
 		this.connection.off('file_created', this.onStreamDriveFileCreated);
 		this.connection.off('file_updated', this.onStreamDriveFileUpdated);
+		this.connection.off('file_deleted', this.onStreamDriveFileDeleted);
 		this.connection.off('folder_created', this.onStreamDriveFolderCreated);
 		this.connection.off('folder_updated', this.onStreamDriveFolderUpdated);
 		(this as any).os.streams.driveStream.dispose(this.connectionId);
@@ -167,6 +169,10 @@ export default Vue.extend({
 			}
 		},
 
+		onStreamDriveFileDeleted(fileId) {
+			this.removeFile(fileId);
+		},
+
 		onStreamDriveFolderCreated(folder) {
 			this.addFolder(folder, true);
 		},
diff --git a/src/client/app/mobile/views/components/drive.file-detail.vue b/src/client/app/mobile/views/components/drive.file-detail.vue
index ad29135268..f6a22f95f0 100644
--- a/src/client/app/mobile/views/components/drive.file-detail.vue
+++ b/src/client/app/mobile/views/components/drive.file-detail.vue
@@ -34,15 +34,10 @@
 	</div>
 	<div class="menu">
 		<div>
-			<a :href="`${file.url}?download`" :download="file.name">
-				%fa:download%%i18n:@download%
-			</a>
-			<button @click="rename">
-				%fa:pencil-alt%%i18n:@rename%
-			</button>
-			<button @click="move">
-				%fa:R folder-open%%i18n:@move%
-			</button>
+			<a :href="`${file.url}?download`" :download="file.name">%fa:download%%i18n:@download%</a>
+			<button @click="rename">%fa:pencil-alt%%i18n:@rename%</button>
+			<button @click="move">%fa:R folder-open%%i18n:@move%</button>
+			<button @click="del">%fa:trash-alt R%%i18n:@delete%</button>
 		</div>
 	</div>
 	<div class="exif" v-show="exif">
@@ -112,6 +107,13 @@ export default Vue.extend({
 				});
 			});
 		},
+		del() {
+			(this as any).api('drive/files/delete', {
+				fileId: this.file.id
+			}).then(() => {
+				this.browser.cd(this.file.folderId, true);
+			});
+		},
 		showCreatedAt() {
 			alert(new Date(this.file.createdAt).toLocaleString());
 		},
diff --git a/src/client/app/mobile/views/components/drive.vue b/src/client/app/mobile/views/components/drive.vue
index 8adf6d8543..c313d225e4 100644
--- a/src/client/app/mobile/views/components/drive.vue
+++ b/src/client/app/mobile/views/components/drive.vue
@@ -100,6 +100,7 @@ export default Vue.extend({
 
 		this.connection.on('file_created', this.onStreamDriveFileCreated);
 		this.connection.on('file_updated', this.onStreamDriveFileUpdated);
+		this.connection.on('file_deleted', this.onStreamDriveFileDeleted);
 		this.connection.on('folder_created', this.onStreamDriveFolderCreated);
 		this.connection.on('folder_updated', this.onStreamDriveFolderUpdated);
 
@@ -118,6 +119,7 @@ export default Vue.extend({
 	beforeDestroy() {
 		this.connection.off('file_created', this.onStreamDriveFileCreated);
 		this.connection.off('file_updated', this.onStreamDriveFileUpdated);
+		this.connection.off('file_deleted', this.onStreamDriveFileDeleted);
 		this.connection.off('folder_created', this.onStreamDriveFolderCreated);
 		this.connection.off('folder_updated', this.onStreamDriveFolderUpdated);
 		(this as any).os.streams.driveStream.dispose(this.connectionId);
@@ -136,6 +138,10 @@ export default Vue.extend({
 			}
 		},
 
+		onStreamDriveFileDeleted(fileId) {
+			this.removeFile(fileId);
+		},
+
 		onStreamDriveFolderCreated(folder) {
 			this.addFolder(folder, true);
 		},
diff --git a/src/server/api/endpoints/drive/files.ts b/src/server/api/endpoints/drive/files.ts
index ab4b18cef4..0f0e3d65a8 100644
--- a/src/server/api/endpoints/drive/files.ts
+++ b/src/server/api/endpoints/drive/files.ts
@@ -37,10 +37,13 @@ module.exports = async (params, user, app) => {
 	const sort = {
 		_id: -1
 	};
+
 	const query = {
 		'metadata.userId': user._id,
-		'metadata.folderId': folderId
+		'metadata.folderId': folderId,
+		'metadata.deletedAt': { $exists: false }
 	} as any;
+
 	if (sinceId) {
 		sort._id = 1;
 		query._id = {
@@ -51,6 +54,7 @@ module.exports = async (params, user, app) => {
 			$lt: untilId
 		};
 	}
+
 	if (type) {
 		query.contentType = new RegExp(`^${type.replace(/\*/g, '.+?')}$`);
 	}
diff --git a/src/server/api/endpoints/drive/files/delete.ts b/src/server/api/endpoints/drive/files/delete.ts
new file mode 100644
index 0000000000..a722b4e825
--- /dev/null
+++ b/src/server/api/endpoints/drive/files/delete.ts
@@ -0,0 +1,32 @@
+import $ from 'cafy'; import ID from '../../../../../cafy-id';
+import DriveFile from '../../../../../models/drive-file';
+import del from '../../../../../services/drive/delete-file';
+import { publishDriveStream } from '../../../../../publishers/stream';
+
+/**
+ * Delete a file
+ */
+module.exports = async (params, user) => {
+	// Get 'fileId' parameter
+	const [fileId, fileIdErr] = $.type(ID).get(params.fileId);
+	if (fileIdErr) throw 'invalid fileId param';
+
+	// Fetch file
+	const file = await DriveFile
+		.findOne({
+			_id: fileId,
+			'metadata.userId': user._id
+		});
+
+	if (file === null) {
+		throw 'file-not-found';
+	}
+
+	// Delete
+	await del(file);
+
+	// Publish file_deleted event
+	publishDriveStream(user._id, 'file_deleted', file._id);
+
+	return;
+};
diff --git a/src/services/drive/add-file.ts b/src/services/drive/add-file.ts
index ace1a6d623..d7f71e8665 100644
--- a/src/services/drive/add-file.ts
+++ b/src/services/drive/add-file.ts
@@ -9,13 +9,14 @@ import * as debug from 'debug';
 import fileType = require('file-type');
 import prominence = require('prominence');
 
-import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile, DriveFileChunk } from '../../models/drive-file';
+import DriveFile, { IMetadata, getDriveFileBucket, IDriveFile } from '../../models/drive-file';
 import DriveFolder from '../../models/drive-folder';
 import { pack } from '../../models/drive-file';
 import event, { publishDriveStream } from '../../publishers/stream';
 import { isLocalUser, IUser, IRemoteUser } from '../../models/user';
-import DriveFileThumbnail, { getDriveFileThumbnailBucket, DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail';
+import { getDriveFileThumbnailBucket } from '../../models/drive-file-thumbnail';
 import genThumbnail from '../../drive/gen-thumbnail';
+import delFile from './delete-file';
 
 const gm = _gm.subClass({
 	imageMagick: true
@@ -58,31 +59,7 @@ async function deleteOldFile(user: IRemoteUser) {
 	});
 
 	if (oldFile) {
-		// チャンクをすべて削除
-		DriveFileChunk.remove({
-			files_id: oldFile._id
-		});
-
-		DriveFile.update({ _id: oldFile._id }, {
-			$set: {
-				'metadata.deletedAt': new Date(),
-				'metadata.isExpired': true
-			}
-		});
-
-		//#region サムネイルもあれば削除
-		const thumbnail = await DriveFileThumbnail.findOne({
-			'metadata.originalId': oldFile._id
-		});
-
-		if (thumbnail) {
-			DriveFileThumbnailChunk.remove({
-				files_id: thumbnail._id
-			});
-
-			DriveFileThumbnail.remove({ _id: thumbnail._id });
-		}
-		//#endregion
+		delFile(oldFile, true);
 	}
 }
 
diff --git a/src/services/drive/delete-file.ts b/src/services/drive/delete-file.ts
new file mode 100644
index 0000000000..a8ed13bd77
--- /dev/null
+++ b/src/services/drive/delete-file.ts
@@ -0,0 +1,30 @@
+import DriveFile, { DriveFileChunk, IDriveFile } from "../../models/drive-file";
+import DriveFileThumbnail, { DriveFileThumbnailChunk } from '../../models/drive-file-thumbnail';
+
+export default async function(file: IDriveFile, isExpired = false) {
+	// チャンクをすべて削除
+	await DriveFileChunk.remove({
+		files_id: file._id
+	});
+
+	await DriveFile.update({ _id: file._id }, {
+		$set: {
+			'metadata.deletedAt': new Date(),
+			'metadata.isExpired': isExpired
+		}
+	});
+
+	//#region サムネイルもあれば削除
+	const thumbnail = await DriveFileThumbnail.findOne({
+		'metadata.originalId': file._id
+	});
+
+	if (thumbnail) {
+		await DriveFileThumbnailChunk.remove({
+			files_id: thumbnail._id
+		});
+
+		await DriveFileThumbnail.remove({ _id: thumbnail._id });
+	}
+	//#endregion
+}