diff --git a/README.md b/README.md
index a67a8631..9398da11 100644
--- a/README.md
+++ b/README.md
@@ -150,7 +150,7 @@ It cannot see, access nor modify, any other files in your Google Drive.
 7. Use [<ins>Context menu</ins>](#context-menu) to transfer selected text to My Notes on other computers.
 8. Use [<ins>Custom theme</ins>](#custom-theme) to customize the look of My Notes in any way as needed.
 9. Drag and Drop selected text onto a note's name in the Sidebar to insert the text into the note.
-10. Drag and Drop a TXT file anywhere in the bottom part of the Sidebar (the area with 3 icons) to import the file as a new note.
+10. Drag and Drop a TXT or HTML file anywhere in the bottom part of the Sidebar (the area with 3 icons) to import the file as a new note.
 11. Drag the Sidebar line to resize the Sidebar, double-click on the Sidebar line to restore the original Sidebar width.
 
 <br><br>
diff --git a/package-lock.json b/package-lock.json
index 91dc0460..e08c3a77 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
       "license": "MIT",
       "dependencies": {
         "clsx": "^1.1.1",
+        "fflate": "^0.7.1",
         "preact": "10.5.14"
       },
       "devDependencies": {
@@ -2991,6 +2992,11 @@
         "bser": "2.1.1"
       }
     },
+    "node_modules/fflate": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.1.tgz",
+      "integrity": "sha512-VYM2Xy1gSA5MerKzCnmmuV2XljkpKwgJBKezW+495TTnTCh1x5HcYa1aH8wRU/MfTGhW4ziXqgwprgQUVl3Ohw=="
+    },
     "node_modules/file-entry-cache": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -8329,6 +8335,11 @@
         "bser": "2.1.1"
       }
     },
+    "fflate": {
+      "version": "0.7.1",
+      "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.7.1.tgz",
+      "integrity": "sha512-VYM2Xy1gSA5MerKzCnmmuV2XljkpKwgJBKezW+495TTnTCh1x5HcYa1aH8wRU/MfTGhW4ziXqgwprgQUVl3Ohw=="
+    },
     "file-entry-cache": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
diff --git a/package.json b/package.json
index 03e7895f..8114a15d 100644
--- a/package.json
+++ b/package.json
@@ -38,6 +38,7 @@
   },
   "dependencies": {
     "clsx": "^1.1.1",
+    "fflate": "^0.7.1",
     "preact": "10.5.14"
   }
 }
diff --git a/src/notes.tsx b/src/notes.tsx
index 39ed7b99..d5483774 100644
--- a/src/notes.tsx
+++ b/src/notes.tsx
@@ -38,6 +38,7 @@ import { sendMessage } from "messages";
 import notesHistory from "notes/history";
 import keyboardShortcuts, { KeyboardShortcut } from "notes/keyboard-shortcuts";
 import { Command, commands } from "notes/commands";
+import { exportNote } from "notes/export";
 
 const getFocusOverride = (): boolean => new URL(window.location.href).searchParams.get("focus") === "";
 const getActiveFromUrl = (): string => new URL(window.location.href).searchParams.get("note") || ""; // Bookmark
@@ -628,10 +629,14 @@ const Notes = (): h.JSX.Element => {
             });
           },
           locked: notesProps.notes[noteName].locked ?? false,
-          toggleLocked: (noteName) => {
+          onToggleLocked: (noteName) => {
             setContextMenuProps(null);
             tabId && notesRef.current && setLocked(noteName, !(notesProps.notes[noteName].locked ?? false), tabId, notesRef.current);
           },
+          onExport: (noteName) => {
+            setContextMenuProps(null);
+            exportNote(noteName);
+          },
         })}
         onNewNote={() => onNewNote()}
         sync={sync}
diff --git a/src/notes/components/ContextMenu.tsx b/src/notes/components/ContextMenu.tsx
index 3f84df55..6fbbb297 100644
--- a/src/notes/components/ContextMenu.tsx
+++ b/src/notes/components/ContextMenu.tsx
@@ -9,11 +9,12 @@ export interface ContextMenuProps {
   onRename: (noteName: string) => void
   onDelete: (noteName: string) => void
   locked: boolean
-  toggleLocked: (noteName: string) => void
+  onToggleLocked: (noteName: string) => void
+  onExport: (noteName: string) => void
 }
 
 const ContextMenu = ({
-  noteName, x, y, onRename, onDelete, locked, toggleLocked,
+  noteName, x, y, onRename, onDelete, locked, onToggleLocked, onExport,
 }: ContextMenuProps): h.JSX.Element => {
   const [offsetHeight, setOffsetHeight] = useState<number>(0);
   const ref = useRef<HTMLDivElement>(null);
@@ -40,7 +41,8 @@ const ContextMenu = ({
     }}>
       <div class={clsx("action", locked && "disabled")} onClick={() => !locked && onRename(noteName)}>Rename</div>
       <div class={clsx("action", locked && "disabled")} onClick={() => !locked && onDelete(noteName)}>Delete</div>
-      <div class="action" onClick={() => toggleLocked(noteName)}>{locked ? "Unlock" : "Lock"}</div>
+      <div class="action" onClick={() => onToggleLocked(noteName)}>{locked ? "Unlock" : "Lock"}</div>
+      <div class="action" onClick={() => onExport(noteName)}>Export</div>
     </div>
   );
 };
diff --git a/src/notes/export/index.ts b/src/notes/export/index.ts
new file mode 100644
index 00000000..3d9c7328
--- /dev/null
+++ b/src/notes/export/index.ts
@@ -0,0 +1,31 @@
+import { zipSync, Zippable } from "fflate";
+import { NotesObject } from "shared/storage/schema";
+import { downloadBlob } from "shared/download";
+
+export const exportNote = (noteName: string): void => chrome.storage.local.get("notes", (local) => {
+  const { notes } = local as { notes: NotesObject };
+  if (!(noteName in notes)) {
+    return; // there is no note to export
+  }
+
+  const encoder = new TextEncoder();
+  const data = encoder.encode(notes[noteName].content);
+
+  downloadBlob(data, `${noteName}.html`, "text/html");
+});
+
+export const exportNotes = (): void => chrome.storage.local.get("notes", (local) => {
+  const { notes } = local as { notes: NotesObject };
+  if (!Object.keys(notes).length) {
+    return; // there are no notes to export
+  }
+
+  const encoder = new TextEncoder();
+  const data: Zippable = Object.keys(notes).reduce((acc, curr) => {
+    acc[`${curr}.html`] = encoder.encode(notes[curr].content);
+    return acc;
+  }, {} as Zippable);
+
+  const gzipped = zipSync(data, { level: 0 });
+  downloadBlob(gzipped, "notes.zip", "application/zip");
+});
diff --git a/src/notes/import/index.ts b/src/notes/import/index.ts
index 1c24f4f7..dee19e66 100644
--- a/src/notes/import/index.ts
+++ b/src/notes/import/index.ts
@@ -1,7 +1,12 @@
 import { readFile } from "./read-file";
 
+const SUPPORTED_FILE_TYPES = [
+  "text/plain",
+  "text/html",
+];
+
 export const importNoteFromTxtFile = (file: File, callback: () => void): void => {
-  if (!file.type.match("text/plain")) {
+  if (!SUPPORTED_FILE_TYPES.includes(file.type)) {
     callback();
     return;
   }
diff --git a/src/options.tsx b/src/options.tsx
index ffcf563e..29b169f3 100644
--- a/src/options.tsx
+++ b/src/options.tsx
@@ -6,11 +6,13 @@ import __Size from "options/Size";
 import __Theme from "options/Theme";
 import __KeyboardShortcuts from "options/KeyboardShortcuts";
 import __Options from "options/Options";
+import __Export from "options/Export";
 import __Version from "options/Version";
 
 import {
   Os,
   Storage,
+  NotesObject,
   RegularFont,
   GoogleFont,
   Theme,
@@ -21,6 +23,7 @@ import { setTheme as setThemeCore } from "themes/set-theme";
 const Options = (): h.JSX.Element => {
   const [os, setOs] = useState<Os | undefined>(undefined);
   const [version] = useState<string>(chrome.runtime.getManifest().version);
+  const [notesCount, setNotesCount] = useState<number>(0);
   const [font, setFont] = useState<RegularFont | GoogleFont | undefined>(undefined);
   const [size, setSize] = useState<number>(0);
   const [theme, setTheme] = useState<Theme | undefined>(undefined);
@@ -34,6 +37,7 @@ const Options = (): h.JSX.Element => {
     chrome.runtime.getPlatformInfo((platformInfo) => setOs(platformInfo.os === "mac" ? "mac" : "other"));
 
     chrome.storage.local.get([
+      "notes",
       "font",
       "size",
       "theme",
@@ -45,6 +49,7 @@ const Options = (): h.JSX.Element => {
     ], items => {
       const local = items as Storage;
 
+      setNotesCount(Object.keys(local.notes).length);
       setFont(local.font);
       setSize(local.size);
       setTheme(local.theme);
@@ -60,6 +65,12 @@ const Options = (): h.JSX.Element => {
         return;
       }
 
+      if (changes["notes"]) {
+        const newValue: NotesObject = changes["notes"].newValue;
+        const newNotesCount = Object.keys(newValue).length;
+        setNotesCount(newNotesCount);
+      }
+
       if (changes["font"]) {
         setFont(changes["font"].newValue);
       }
@@ -116,6 +127,7 @@ const Options = (): h.JSX.Element => {
         tab={tab}
         tabSize={tabSize}
       />
+      <__Export canExport={notesCount > 0} />
       <__Version version={version} />
     </Fragment>
   );
diff --git a/src/options/Export.tsx b/src/options/Export.tsx
new file mode 100644
index 00000000..5b2b1915
--- /dev/null
+++ b/src/options/Export.tsx
@@ -0,0 +1,31 @@
+import { h, Fragment } from "preact";
+import clsx from "clsx";
+import { exportNotes } from "notes/export";
+
+let locked = false;
+
+interface ExportProps {
+  canExport: boolean
+}
+
+const Export = ({ canExport }: ExportProps): h.JSX.Element => (
+  <Fragment>
+    <h2>Export</h2>
+    <input
+      type="button"
+      class={clsx("bold", "button", !canExport && "disabled")}
+      value="Export all notes"
+      onClick={() => {
+        if (!canExport || locked) {
+          return;
+        }
+
+        locked = true;
+        exportNotes();
+        window.setTimeout(() => locked = false, 1000);
+      }}
+    />
+  </Fragment>
+);
+
+export default Export;
diff --git a/src/options/Font.tsx b/src/options/Font.tsx
index 2979cedd..3a15f0f5 100644
--- a/src/options/Font.tsx
+++ b/src/options/Font.tsx
@@ -88,6 +88,7 @@ const Font = ({ font }: FontProps): h.JSX.Element => {
           <input
             type="text"
             placeholder="Font Name (E.g. Roboto Mono)"
+            class="input"
             value={googleFontName}
             onInput={(event) => {
               setGoogleFontName((event.target as HTMLInputElement).value);
@@ -96,8 +97,7 @@ const Font = ({ font }: FontProps): h.JSX.Element => {
           />
           <input
             type="submit"
-            id="submit"
-            class={clsx("bold", (googleFontName !== font?.name) && "active")}
+            class={clsx("bold", "button", (googleFontName === font?.name) && "disabled")}
             value={googleSubmitButtonText}
             onClick={() => {
               const trimmedGoogleFontName = googleFontName.trim();
diff --git a/src/options/Options.tsx b/src/options/Options.tsx
index 3ee27e2c..1d501d06 100644
--- a/src/options/Options.tsx
+++ b/src/options/Options.tsx
@@ -94,7 +94,7 @@ const Options = ({ sync, autoSync, tab, tabSize }: OptionsProps): h.JSX.Element
             </div>
             <div class={clsx("space-top", !tab && "disabled")}>
               <label>Tab size:</label>
-              <select name="tab-size" value={tabSize} onChange={(event) => {
+              <select name="tab-size" class="select" value={tabSize} onChange={(event) => {
                 const newTabSize: number = parseInt((event.target as HTMLSelectElement).value);
                 chrome.storage.local.set({ tabSize: newTabSize });
               }}>
diff --git a/src/shared/download/index.ts b/src/shared/download/index.ts
new file mode 100644
index 00000000..2986b3db
--- /dev/null
+++ b/src/shared/download/index.ts
@@ -0,0 +1,17 @@
+export const downloadURL = (data: string, fileName: string): void => {
+  const a = document.createElement("a");
+  a.href = data;
+  a.download = fileName;
+  a.click();
+  a.remove();
+};
+
+export const downloadBlob = (data: Uint8Array, fileName: string, mimeType: string): void => {
+  const blob = new Blob([data], {
+    type: mimeType,
+  });
+
+  const url = window.URL.createObjectURL(blob);
+  downloadURL(url, fileName);
+  window.setTimeout(() => window.URL.revokeObjectURL(url), 2000);
+};
diff --git a/static/options.css b/static/options.css
index c44e5155..cbddd36a 100644
--- a/static/options.css
+++ b/static/options.css
@@ -23,13 +23,38 @@ input[type="radio"], input[type='checkbox'] {
   margin: 0 10px 0 2px;
 }
 
-select { border-radius: 3px; }
-
 .separator { padding: 0 12px; }
 .bold { font-weight: bold; }
 .space-top { margin-top: 1em; }
 .space-left { margin-left: 1em; }
 
+.disabled {
+  opacity: .3;
+  user-select: none;
+  pointer-events: none;
+}
+
+/* Inputs */
+
+.button {
+  cursor: pointer;
+}
+
+.button, .input, .select {
+  max-width: 500px;
+  box-sizing: content-box;
+  outline: none;
+  border: 1px solid silver;
+  padding: 12px;
+  border-radius: 3px;
+}
+
+#dark .button,
+#dark .input,
+#dark .select {
+  border-color: transparent;
+}
+
 /* Selection */
 
 .selection { padding: 10px 0; }
@@ -65,9 +90,6 @@ body#dark .comment {
 .font-category { cursor: pointer; }
 .font-category.active { text-decoration: underline; }
 
-#submit { opacity: .3; }
-#submit.active { opacity: 1; cursor: pointer; }
-
 .font-area .selection {
   font-size: 80%;
   display: flex;
@@ -82,26 +104,14 @@ body#dark .comment {
 #google-fonts-area ol { margin-top: 0; }
 #google-fonts-area ol li { line-height: 2em; }
 
-#google-fonts-area input, select {
-  max-width: 500px;
-  box-sizing: content-box;
-  outline: none;
-  border: 1px solid silver;
-  padding: 12px;
-}
-
-#dark #google-fonts-area input, select {
-  border-color: transparent;
+#google-fonts-area .input {
+  border-bottom-left-radius: 0;
+  border-bottom-right-radius: 0;
 }
 
-#google-fonts-area input[type="text"] {
-  border-top-left-radius: 3px;
-  border-top-right-radius: 3px;
-}
-
-#google-fonts-area input[type="submit"] {
-  border-bottom-left-radius: 3px;
-  border-bottom-right-radius: 3px;
+#google-fonts-area .button {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
 }
 
 /* Font size */
@@ -189,16 +199,6 @@ body#dark .comment {
   word-break: break-all;
 }
 
-div.disabled {
-  opacity: .3;
-  user-select: none;
-}
-
-div.disabled input,
-div.disabled select {
-  pointer-events: none;
-}
-
 /* Media Queries */
 
 @media only screen and (max-width: 600px) {