diff --git a/db/migrations/0121__add_hoisting_option.sql b/db/migrations/0121__add_hoisting_option.sql
new file mode 100644
index 000000000..1b0458592
--- /dev/null
+++ b/db/migrations/0121__add_hoisting_option.sql
@@ -0,0 +1,2 @@
+INSERT INTO options (name, value, dateCreated, dateModified, isSynced)
+VALUES ('hoistedNoteId', 'root', '2018-12-11T18:31:00.874Z', '2018-12-11T18:31:00.874Z', 0);
\ No newline at end of file
diff --git a/src/public/javascripts/services/context_menu.js b/src/public/javascripts/services/context_menu.js
index 2ee0e552e..99416cf02 100644
--- a/src/public/javascripts/services/context_menu.js
+++ b/src/public/javascripts/services/context_menu.js
@@ -4,6 +4,10 @@ function initContextMenu(event, contextMenuItems, selectContextMenuItem) {
     $contextMenuContainer.empty();
 
     for (const item of contextMenuItems) {
+        if (item.hidden) {
+            continue;
+        }
+
         if (item.title === '----') {
             $contextMenuContainer.append($("
").addClass("dropdown-divider"));
         } else {
diff --git a/src/public/javascripts/services/hoisted_note.js b/src/public/javascripts/services/hoisted_note.js
new file mode 100644
index 000000000..26c863223
--- /dev/null
+++ b/src/public/javascripts/services/hoisted_note.js
@@ -0,0 +1,25 @@
+import optionsInit from './options_init.js';
+import server from "./server.js";
+
+let hoistedNoteId;
+
+optionsInit.optionsReady.then(options => {
+    hoistedNoteId = options['hoistedNoteId'];
+});
+
+async function getHoistedNoteId() {
+    await optionsInit.optionsReady;
+
+    return hoistedNoteId;
+}
+
+async function setHoistedNoteId(noteId) {
+    hoistedNoteId = noteId;
+
+    await server.put('options/hoistedNoteId/' + noteId);
+}
+
+export default {
+    getHoistedNoteId,
+    setHoistedNoteId
+}
\ No newline at end of file
diff --git a/src/public/javascripts/services/tree_builder.js b/src/public/javascripts/services/tree_builder.js
index 09c564470..945ea33e7 100644
--- a/src/public/javascripts/services/tree_builder.js
+++ b/src/public/javascripts/services/tree_builder.js
@@ -4,13 +4,18 @@ import Branch from "../entities/branch.js";
 import server from "./server.js";
 import treeCache from "./tree_cache.js";
 import messagingService from "./messaging.js";
+import hoistedNoteService from "./hoisted_note.js";
 
 async function prepareTree(noteRows, branchRows, relations) {
     utils.assertArguments(noteRows, branchRows, relations);
 
     treeCache.load(noteRows, branchRows, relations);
 
-    return [ await prepareNode(await treeCache.getBranch('root')) ];
+    const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
+    const hoistedNote = await treeCache.getNote(hoistedNoteId);
+    const hoistedBranch = (await hoistedNote.getBranches())[0];
+
+    return [ await prepareNode(hoistedBranch) ];
 }
 
 async function prepareBranch(note) {
diff --git a/src/public/javascripts/services/tree_context_menu.js b/src/public/javascripts/services/tree_context_menu.js
index ac21f13b2..fa44e2f46 100644
--- a/src/public/javascripts/services/tree_context_menu.js
+++ b/src/public/javascripts/services/tree_context_menu.js
@@ -10,7 +10,7 @@ import exportDialog from '../dialogs/export.js';
 import infoService from "./info.js";
 import treeCache from "./tree_cache.js";
 import syncService from "./sync.js";
-import contextMenuService from "./context_menu.js";
+import hoistedNoteService from './hoisted_note.js';
 
 const $tree = $("#tree");
 
@@ -83,6 +83,8 @@ const contextMenuItems = [
     {title: "Insert child note Ctrl+P", cmd: "insertChildNote", uiIcon: "plus"},
     {title: "Delete", cmd: "delete", uiIcon: "trash"},
     {title: "----"},
+    {title: "Hoist note", cmd: "hoist", uiIcon: "arrow-up"},
+    {title: "Unhoist note", cmd: "unhoist", uiIcon: "arrow-up"},
     {title: "Edit branch prefix F2", cmd: "editBranchPrefix", uiIcon: "pencil"},
     {title: "----"},
     {title: "Protect subtree", cmd: "protectSubtree", uiIcon: "shield-check"},
@@ -101,6 +103,16 @@ const contextMenuItems = [
     {title: "Sort alphabetically Alt+S", cmd: "sortAlphabetically", uiIcon: "arrows-v"}
 ];
 
+function hideItem(cmd, hidden) {
+    const item = contextMenuItems.find(item => item.cmd === cmd);
+
+    if (!item) {
+        throw new Error(`Command ${cmd} has not been found!`);
+    }
+
+    item.hidden = hidden;
+}
+
 function enableItem(cmd, enabled) {
     const item = contextMenuItems.find(item => item.cmd === cmd);
     
@@ -130,6 +142,11 @@ async function getContextMenuItems(event) {
     enableItem("export", note.type !== 'search');
     enableItem("editBranchPrefix", isNotRoot && parentNote.type !== 'search');
 
+    const hoistedNoteId = await hoistedNoteService.getHoistedNoteId();
+
+    hideItem("hoist", note.noteId === hoistedNoteId);
+    hideItem("unhoist", note.noteId !== hoistedNoteId || !isNotRoot);
+
     // Activate node on right-click
     node.setActive();
 
@@ -194,6 +211,12 @@ function selectContextMenuItem(event, cmd) {
     else if (cmd === "sortAlphabetically") {
         treeService.sortAlphabetically(node.data.noteId);
     }
+    else if (cmd === "hoist") {
+        hoistedNoteService.setHoistedNoteId(node.data.noteId);
+    }
+    else if (cmd === "unhoist") {
+        hoistedNoteService.setHoistedNoteId('root');
+    }
     else {
         messagingService.logError("Unknown command: " + cmd);
     }
diff --git a/src/routes/api/options.js b/src/routes/api/options.js
index b2cb0c690..1f9a8c9aa 100644
--- a/src/routes/api/options.js
+++ b/src/routes/api/options.js
@@ -6,7 +6,7 @@ const log = require('../../services/log');
 
 // options allowed to be updated directly in options dialog
 const ALLOWED_OPTIONS = ['protectedSessionTimeout', 'noteRevisionSnapshotTimeInterval',
-    'zoomFactor', 'theme', 'syncServerHost', 'syncServerTimeout', 'syncProxy', 'leftPaneMinWidth', 'leftPaneWidthPercent'];
+    'zoomFactor', 'theme', 'syncServerHost', 'syncServerTimeout', 'syncProxy', 'leftPaneMinWidth', 'leftPaneWidthPercent', 'hoistedNoteId'];
 
 async function getOptions() {
     return await optionService.getOptionsMap(ALLOWED_OPTIONS);
diff --git a/src/routes/api/tree.js b/src/routes/api/tree.js
index cebc547b9..97dbb527c 100644
--- a/src/routes/api/tree.js
+++ b/src/routes/api/tree.js
@@ -50,18 +50,20 @@ async function getRelations(noteIds) {
 }
 
 async function getTree() {
+    const hoistedNoteId = await optionService.getOption('hoistedNoteId');
+
     // we fetch all branches of notes, even if that particular branch isn't visible
     // this allows us to e.g. detect and properly display clones
     const branches = await sql.getRows(`
         WITH RECURSIVE
             tree(branchId, noteId, isExpanded) AS (
-            SELECT branchId, noteId, isExpanded FROM branches WHERE branchId = 'root' 
+            SELECT branchId, noteId, isExpanded FROM branches WHERE noteId = ? 
             UNION ALL
             SELECT branches.branchId, branches.noteId, branches.isExpanded FROM branches
               JOIN tree ON branches.parentNoteId = tree.noteId
               WHERE tree.isExpanded = 1 AND branches.isDeleted = 0
           )
-        SELECT branches.* FROM tree JOIN branches USING(noteId) WHERE branches.isDeleted = 0 ORDER BY branches.notePosition`);
+        SELECT branches.* FROM tree JOIN branches USING(noteId) WHERE branches.isDeleted = 0 ORDER BY branches.notePosition`, [hoistedNoteId]);
 
     const noteIds = Array.from(new Set(branches.map(b => b.noteId)));
 
diff --git a/src/services/app_info.js b/src/services/app_info.js
index a238a1645..5576b99ef 100644
--- a/src/services/app_info.js
+++ b/src/services/app_info.js
@@ -3,7 +3,7 @@
 const build = require('./build');
 const packageJson = require('../../package');
 
-const APP_DB_VERSION = 120;
+const APP_DB_VERSION = 121;
 const SYNC_VERSION = 2;
 
 module.exports = {