diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 2d6126197..db08ef19f 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -425,6 +425,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 "lng_settings_custom_spellchecker" = "Use spell checker";
 "lng_settings_manage_dictionaries" = "Manage dictionaries";
 "lng_settings_manage_enabled_dictionary" = "Dictionary is enabled";
+"lng_settings_manage_remove_dictionary" = "Remove Dictionary";
 
 "lng_backgrounds_header" = "Choose your new chat background";
 "lng_theme_sure_keep" = "Keep this theme?";
diff --git a/Telegram/SourceFiles/boxes/dictionaries_manager.cpp b/Telegram/SourceFiles/boxes/dictionaries_manager.cpp
index 98ba77e1a..cd8957ce5 100644
--- a/Telegram/SourceFiles/boxes/dictionaries_manager.cpp
+++ b/Telegram/SourceFiles/boxes/dictionaries_manager.cpp
@@ -9,6 +9,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 
 #ifndef TDESKTOP_DISABLE_SPELLCHECK
 
+#include "base/event_filter.h"
 #include "chat_helpers/spellchecker_common.h"
 #include "core/application.h"
 #include "main/main_account.h"
@@ -21,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 #include "ui/wrap/vertical_layout.h"
 #include "ui/widgets/buttons.h"
 #include "ui/widgets/labels.h"
+#include "ui/widgets/popup_menu.h"
 #include "ui/wrap/slide_wrap.h"
 #include "ui/effects/animations.h"
 
@@ -68,6 +70,12 @@ inline auto DictExists(int langId) {
 	return Spellchecker::DictionaryExists(langId);
 }
 
+inline auto FilterEnabledDict(Dictionaries dicts) {
+	return dicts | ranges::views::filter(
+		DictExists
+	) | ranges::to_vector;
+}
+
 DictState ComputeState(int id, bool enabled) {
 	const auto result = enabled ? DictState(Active()) : DictState(Ready());
 	if (DictExists(id)) {
@@ -151,6 +159,8 @@ auto AddButtonWithLoader(
 
 	const auto buttonState = button->lifetime()
 		.make_state<rpl::variable<DictState>>();
+	const auto dictionaryRemoved = button->lifetime()
+		.make_state<rpl::event_stream<>>();
 
 	const auto label = Ui::CreateChild<Ui::FlatLabel>(
 		button,
@@ -188,10 +198,15 @@ auto AddButtonWithLoader(
 		rpl::single(
 			buttonEnabled
 		) | rpl::then(
-			buttonState->value(
-			) | rpl::filter([](const DictState &state) {
-				return state.is<Failed>();
-			}) | rpl::map([](const auto &state) {
+			rpl::merge(
+				dictionaryRemoved->events(),
+				buttonState->value(
+				) | rpl::filter([](const DictState &state) {
+					return state.is<Failed>();
+				}) | rpl::map([] {
+					return rpl::empty_value();
+				})
+			) | rpl::map([]() {
 				return false;
 			})
 		)
@@ -205,7 +220,13 @@ auto AddButtonWithLoader(
 			: rpl::single(
 				buttonEnabled
 			) | rpl::then(
-				button->toggledValue()
+				rpl::merge(
+					dictionaryRemoved->events(
+					) | rpl::map([] {
+						return false;
+					}),
+					button->toggledValue()
+				)
 			) | rpl::map([=](auto enabled) {
 				return ComputeState(id, enabled);
 			});
@@ -233,6 +254,29 @@ auto AddButtonWithLoader(
 		}
 	}, button->lifetime());
 
+	const auto contextMenu = button->lifetime()
+		.make_state<base::unique_qptr<Ui::PopupMenu>>();
+	const auto showMenu = [=] {
+		if (!DictExists(id)) {
+			return false;
+		}
+		*contextMenu = base::make_unique_q<Ui::PopupMenu>(button);
+		contextMenu->get()->addAction(
+			tr::lng_settings_manage_remove_dictionary(tr::now), [=] {
+			Spellchecker::RemoveDictionary(id);
+			dictionaryRemoved->fire({});
+		});
+		contextMenu->get()->popup(QCursor::pos());
+		return true;
+	};
+
+	base::install_event_filter(button, [=](not_null<QEvent*> e) {
+		if (e->type() == QEvent::ContextMenu && showMenu()) {
+			return base::EventFilterResult::Cancel;
+		}
+		return base::EventFilterResult::Continue;
+	});
+
 	return button;
 }
 
@@ -281,11 +325,8 @@ void ManageDictionariesBox::prepare() {
 	setTitle(tr::lng_settings_manage_dictionaries());
 
 	addButton(tr::lng_settings_save(), [=] {
-		auto enabledRows = inner->enabledRows();
 		_session->settings().setDictionariesEnabled(
-			enabledRows | ranges::views::filter(
-				DictExists
-			) | ranges::to_vector);
+			FilterEnabledDict(inner->enabledRows()));
 		_session->saveSettingsDelayed();
 		// Ignore boxClosing() when the Save button was pressed.
 		lifetime().destroy();
@@ -294,7 +335,8 @@ void ManageDictionariesBox::prepare() {
 	addButton(tr::lng_close(), [=] { closeBox(); });
 
 	boxClosing() | rpl::start_with_next([=] {
-		_session->settings().setDictionariesEnabled(initialEnabledRows);
+		_session->settings().setDictionariesEnabled(
+			FilterEnabledDict(initialEnabledRows));
 		_session->saveSettingsDelayed();
 	}, lifetime());
 
diff --git a/Telegram/SourceFiles/chat_helpers/spellchecker_common.cpp b/Telegram/SourceFiles/chat_helpers/spellchecker_common.cpp
index a589f39c3..07e6ef012 100644
--- a/Telegram/SourceFiles/chat_helpers/spellchecker_common.cpp
+++ b/Telegram/SourceFiles/chat_helpers/spellchecker_common.cpp
@@ -134,6 +134,17 @@ bool DictionaryExists(int langId) {
 	return (bad == end(kDictExtensions));
 }
 
+bool RemoveDictionary(int langId) {
+	if (!langId) {
+		return true;
+	}
+	const auto fileName = Spellchecker::LocaleFromLangId(langId).name();
+	const auto folder = qsl("%1/%2/")
+		.arg(DictionariesPath())
+		.arg(fileName);
+	return QDir(folder).removeRecursively();
+}
+
 bool WriteDefaultDictionary() {
 	// This is an unused function.
 	const auto en = QLocale::English;
diff --git a/Telegram/SourceFiles/chat_helpers/spellchecker_common.h b/Telegram/SourceFiles/chat_helpers/spellchecker_common.h
index 0c3a09c4d..db486ebde 100644
--- a/Telegram/SourceFiles/chat_helpers/spellchecker_common.h
+++ b/Telegram/SourceFiles/chat_helpers/spellchecker_common.h
@@ -27,6 +27,8 @@ MTP::DedicatedLoader::Location GetDownloadLocation(int id);
 [[nodiscard]] QString DictPathByLangId(int langId);
 bool UnpackDictionary(const QString &path, int langId);
 [[nodiscard]] bool DictionaryExists(int langId);
+bool RemoveDictionary(int langId);
+[[nodiscard]] bool IsEn(int langId);
 
 bool WriteDefaultDictionary();
 std::vector<Dict> Dictionaries();