diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index a9aec1f..6692098 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -13,10 +13,11 @@ body:
 
               Make sure both Vesktop and Vencord are fully up to date. You can update Vencord by right-clicking the Vesktop tray icon and pressing "Update Vencord"
 
-              Do not report any of the following issues:
+              **DO NOT REPORT** any of the following issues:
               - Purely graphical glitches like flickering, scaling issues, etc: Issue with your gpu. Nothing we can do, update drivers or disable hardware acceleration
               - Vencord related issues: This is the Vesktop repo, not Vencord
-              - Screenshare not starting / black screening on Linux: Issue with your desktop environment, specifically its xdg-desktop-portal
+              - **SCREENSHARE NOT STARTING** / black screening on Linux: Issue with your desktop environment, specifically its xdg-desktop-portal.
+                If you're on flatpak, try using native version. If that also doesn't work, you have to fix your systen. Inspect errors and google around.
 
               Linux users: Please only report issues with supported packages (flatpak and any builds from the README / releases).
               We do not support other packages, like the AUR or Nix packages, so please first make sure your issue is reproducible with official releases,
diff --git a/.github/workflows/meta.yml b/.github/workflows/meta.yml
index 5287c23..2ebc5a3 100644
--- a/.github/workflows/meta.yml
+++ b/.github/workflows/meta.yml
@@ -11,28 +11,28 @@ jobs:
         runs-on: ubuntu-latest
 
         steps:
-        - uses: actions/checkout@v3
-        - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
+            - uses: actions/checkout@v4
+            - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json
 
-        - name: Use Node.js 18.18.2
-          uses: actions/setup-node@v3
-          with:
-              node-version: 18.18.2
+            - name: Use Node.js 20
+              uses: actions/setup-node@v4
+              with:
+                  node-version: 20
 
-        - name: Install dependencies
-          run: pnpm i
+            - name: Install dependencies
+              run: pnpm i
 
-        - name: Update metainfo
-          run: pnpm updateMeta
+            - name: Update metainfo
+              run: pnpm updateMeta
 
-        - name: Commit and merge in changes
-          run: |
-              git config user.name "github-actions[bot]"
-              git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
-              git checkout -b ci/meta-update
-              git add meta/dev.vencord.Vesktop.metainfo.xml
-              git commit -m "Insert release changes for ${{ github.event.release.tag_name }}"
-              git push origin ci/meta-update
-              gh pr create -B main -H ci/meta-update -t "Metainfo for ${{ github.event.release.tag_name }}" -b "This PR updates the metainfo for release ${{ github.event.release.tag_name }}. @lewisakura @Vendicated"
-          env:
-              GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
\ No newline at end of file
+            - name: Commit and merge in changes
+              run: |
+                  git config user.name "github-actions[bot]"
+                  git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
+                  git checkout -b ci/meta-update
+                  git add meta/dev.vencord.Vesktop.metainfo.xml
+                  git commit -m "Insert release changes for ${{ github.event.release.tag_name }}"
+                  git push origin ci/meta-update
+                  gh pr create -B main -H ci/meta-update -t "Metainfo for ${{ github.event.release.tag_name }}" -b "This PR updates the metainfo for release ${{ github.event.release.tag_name }}. @lewisakura @Vendicated"
+              env:
+                  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 6968b73..9de1bc5 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -22,13 +22,13 @@ jobs:
                       platform: windows
 
         steps:
-            - uses: actions/checkout@v3
-            - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
+            - uses: actions/checkout@v4
+            - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json
 
-            - name: Use Node.js 18.18.2
-              uses: actions/setup-node@v3
+            - name: Use Node.js 20
+              uses: actions/setup-node@v4
               with:
-                  node-version: 18.18.2
+                  node-version: 20
                   cache: "pnpm"
 
             - name: Install dependencies
@@ -43,7 +43,7 @@ jobs:
                   pnpm electron-builder --${{ matrix.platform }} --publish always
               env:
                   GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-                  
+
             - name: Run Electron Builder
               if: ${{ matrix.platform == 'mac' }}
               run: |
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 6d88280..daa62a5 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -11,13 +11,13 @@ jobs:
         runs-on: ubuntu-latest
 
         steps:
-            - uses: actions/checkout@v3
-            - uses: pnpm/action-setup@v2 # Install pnpm using packageManager key in package.json
+            - uses: actions/checkout@v4
+            - uses: pnpm/action-setup@v4 # Install pnpm using packageManager key in package.json
 
-            - name: Use Node.js 18.18.2
-              uses: actions/setup-node@v3
+            - name: Use Node.js 20
+              uses: actions/setup-node@v4
               with:
-                  node-version: 18.18.2
+                  node-version: 20
                   cache: "pnpm"
 
             - name: Install dependencies
diff --git a/meta/dev.vencord.Vesktop.metainfo.xml b/meta/dev.vencord.Vesktop.metainfo.xml
index 889b9fc..2c94c9e 100644
--- a/meta/dev.vencord.Vesktop.metainfo.xml
+++ b/meta/dev.vencord.Vesktop.metainfo.xml
@@ -182,7 +182,7 @@
   https://github.com/Vencord/Vesktop
   
     InstantMessaging
-    AudioVideo
+    Network
   
   
     pointing
@@ -208,4 +208,4 @@
     Privacy
     Mod
   
-
\ No newline at end of file
+
diff --git a/package.json b/package.json
index 67571bd..b00966e 100644
--- a/package.json
+++ b/package.json
@@ -24,7 +24,8 @@
         "updateMeta": "tsx scripts/utils/updateMeta.mts"
     },
     "dependencies": {
-        "arrpc": "github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24"
+        "arrpc": "github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24",
+        "electron-updater": "^6.2.1"
     },
     "optionalDependencies": {
         "@vencord/venmic": "^6.1.0"
@@ -37,7 +38,7 @@
         "@typescript-eslint/parser": "^7.2.0",
         "@vencord/types": "^1.8.4",
         "dotenv": "^16.4.5",
-        "electron": "^31.0.1",
+        "electron": "^31.1.0",
         "electron-builder": "^24.13.3",
         "esbuild": "^0.20.1",
         "eslint": "^8.57.0",
@@ -65,6 +66,7 @@
         "productName": "Vesktop",
         "files": [
             "!*",
+            "!node_modules",
             "dist/js",
             "static",
             "package.json",
@@ -118,8 +120,7 @@
                 {
                     "target": "default",
                     "arch": [
-                        "x64",
-                        "arm64"
+                        "universal"
                     ]
                 }
             ],
@@ -158,8 +159,20 @@
         },
         "win": {
             "target": [
-                "nsis",
-                "zip"
+                {
+                    "target": "nsis",
+                    "arch": [
+                        "x64",
+                        "arm64"
+                    ]
+                },
+                {
+                    "target": "zip",
+                    "arch": [
+                        "x64",
+                        "arm64"
+                    ]
+                }
             ]
         },
         "publish": {
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9cbb7be..ea1758f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -16,6 +16,9 @@ importers:
       arrpc:
         specifier: github:OpenAsar/arrpc#c62ec6a04c8d870530aa6944257fe745f6c59a24
         version: https://codeload.github.com/OpenAsar/arrpc/tar.gz/c62ec6a04c8d870530aa6944257fe745f6c59a24(patch_hash=biyukfa6dww2wxujy4eyvkhrti)
+      electron-updater:
+        specifier: ^6.2.1
+        version: 6.2.1
     optionalDependencies:
       '@vencord/venmic':
         specifier: ^6.1.0
@@ -43,8 +46,8 @@ importers:
         specifier: ^16.4.5
         version: 16.4.5
       electron:
-        specifier: ^31.0.1
-        version: 31.0.1
+        specifier: ^31.1.0
+        version: 31.1.0
       electron-builder:
         specifier: ^24.13.3
         version: 24.13.3(electron-builder-squirrel-windows@24.13.3(dmg-builder@24.13.3))
@@ -429,6 +432,7 @@ packages:
   '@humanwhocodes/config-array@0.11.14':
     resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==}
     engines: {node: '>=10.10.0'}
+    deprecated: Use @eslint/config-array instead
 
   '@humanwhocodes/module-importer@1.0.1':
     resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==}
@@ -436,6 +440,7 @@ packages:
 
   '@humanwhocodes/object-schema@2.0.2':
     resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==}
+    deprecated: Use @eslint/object-schema instead
 
   '@isaacs/cliui@8.0.2':
     resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
@@ -1085,8 +1090,11 @@ packages:
   electron-publish@24.13.1:
     resolution: {integrity: sha512-2ZgdEqJ8e9D17Hwp5LEq5mLQPjqU3lv/IALvgp+4W8VeNhryfGhYEQC/PgDPMrnWUp+l60Ou5SJLsu+k4mhQ8A==}
 
-  electron@31.0.1:
-    resolution: {integrity: sha512-2eBcp4iqLkTsml6mMq+iqrS5u3kJ/2mpOLP7Mj7lo0uNK3OyfNqRS9z1ArsHjBF2/HV250Te/O9nKrwQRTX/+g==}
+  electron-updater@6.2.1:
+    resolution: {integrity: sha512-83eKIPW14qwZqUUM6wdsIRwVKZyjmHxQ4/8G+1C6iS5PdDt7b1umYQyj1/qPpH510GmHEQe4q0kCPe3qmb3a0Q==}
+
+  electron@31.1.0:
+    resolution: {integrity: sha512-TBOwqLxSxnx6+pH6GMri7R3JPH2AkuGJHfWZS0p1HsmN+Qr1T9b0IRJnnehSd/3NZAmAre4ft9Ljec7zjyKFJA==}
     engines: {node: '>= 12.20.55'}
     hasBin: true
 
@@ -1796,9 +1804,15 @@ packages:
   lodash.difference@4.5.0:
     resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==}
 
+  lodash.escaperegexp@4.1.2:
+    resolution: {integrity: sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==}
+
   lodash.flatten@4.4.0:
     resolution: {integrity: sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==}
 
+  lodash.isequal@4.5.0:
+    resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+
   lodash.isplainobject@4.0.6:
     resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
 
@@ -2379,6 +2393,9 @@ packages:
   text-table@0.2.0:
     resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
 
+  tiny-typed-emitter@2.1.0:
+    resolution: {integrity: sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==}
+
   tmp-promise@3.0.3:
     resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==}
 
@@ -3659,7 +3676,20 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  electron@31.0.1:
+  electron-updater@6.2.1:
+    dependencies:
+      builder-util-runtime: 9.2.4
+      fs-extra: 10.1.0
+      js-yaml: 4.1.0
+      lazy-val: 1.0.5
+      lodash.escaperegexp: 4.1.2
+      lodash.isequal: 4.5.0
+      semver: 7.6.0
+      tiny-typed-emitter: 2.1.0
+    transitivePeerDependencies:
+      - supports-color
+
+  electron@31.1.0:
     dependencies:
       '@electron/get': 2.0.3
       '@types/node': 20.11.26
@@ -4520,8 +4550,12 @@ snapshots:
 
   lodash.difference@4.5.0: {}
 
+  lodash.escaperegexp@4.1.2: {}
+
   lodash.flatten@4.4.0: {}
 
+  lodash.isequal@4.5.0: {}
+
   lodash.isplainobject@4.0.6: {}
 
   lodash.merge@4.6.2: {}
@@ -5133,6 +5167,8 @@ snapshots:
 
   text-table@0.2.0: {}
 
+  tiny-typed-emitter@2.1.0: {}
+
   tmp-promise@3.0.3:
     dependencies:
       tmp: 0.2.3
diff --git a/scripts/build/build.mts b/scripts/build/build.mts
index 27f45cc..243381b 100644
--- a/scripts/build/build.mts
+++ b/scripts/build/build.mts
@@ -63,12 +63,6 @@ await Promise.all([
         outfile: "dist/js/preload.js",
         footer: { js: "//# sourceURL=VCDPreload" }
     }),
-    createContext({
-        ...NodeCommonOpts,
-        entryPoints: ["src/updater/preload.ts"],
-        outfile: "dist/js/updaterPreload.js",
-        footer: { js: "//# sourceURL=VCDUpdaterPreload" }
-    }),
     createContext({
         ...CommonOpts,
         globalName: "Vesktop",
diff --git a/src/main/constants.ts b/src/main/constants.ts
index 1bce303..40d91a5 100644
--- a/src/main/constants.ts
+++ b/src/main/constants.ts
@@ -37,7 +37,8 @@ if (existsSync(LEGACY_DATA_DIR)) {
         console.error("Migration failed", e);
     }
 }
-app.setPath("sessionData", join(DATA_DIR, "sessionData"));
+const SESSION_DATA_DIR = join(DATA_DIR, "sessionData");
+app.setPath("sessionData", SESSION_DATA_DIR);
 
 export const VENCORD_SETTINGS_DIR = join(DATA_DIR, "settings");
 export const VENCORD_QUICKCSS_FILE = join(VENCORD_SETTINGS_DIR, "quickCss.css");
@@ -47,7 +48,8 @@ export const VENCORD_THEMES_DIR = join(DATA_DIR, "themes");
 // needs to be inline require because of circular dependency
 // as otherwise "DATA_DIR" (which is used by ./settings) will be uninitialised
 export const VENCORD_FILES_DIR =
-    (require("./settings") as typeof import("./settings")).Settings.store.vencordDir || join(DATA_DIR, "vencordDist");
+    (require("./settings") as typeof import("./settings")).State.store.vencordDir ||
+    join(SESSION_DATA_DIR, "vencordFiles");
 
 export const USER_AGENT = `Vesktop/${app.getVersion()} (https://github.com/Vencord/Vesktop)`;
 
@@ -60,10 +62,10 @@ export const DEFAULT_HEIGHT = 720;
 export const DISCORD_HOSTNAMES = ["discord.com", "canary.discord.com", "ptb.discord.com"];
 
 const BrowserUserAgents = {
-    darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
-    linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
+    darwin: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
+    linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",
     windows:
-        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36"
+        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36"
 };
 
 export const BrowserUserAgent = BrowserUserAgents[process.platform] || BrowserUserAgents.windows;
diff --git a/src/main/firstLaunch.ts b/src/main/firstLaunch.ts
index a327e9a..4128097 100644
--- a/src/main/firstLaunch.ts
+++ b/src/main/firstLaunch.ts
@@ -18,11 +18,11 @@ import { Settings, State } from "./settings";
 import { makeLinksOpenExternally } from "./utils/makeLinksOpenExternally";
 
 interface Data {
-    minimizeToTray: boolean;
     discordBranch: "stable" | "canary" | "ptb";
-    autoStart: boolean;
-    importSettings: boolean;
-    richPresence: boolean;
+    minimizeToTray?: "on";
+    autoStart?: "on";
+    importSettings?: "on";
+    richPresence?: "on";
 }
 
 export function createFirstLaunchTour() {
@@ -44,12 +44,12 @@ export function createFirstLaunchTour() {
         if (!msg.startsWith("form:")) return;
         const data = JSON.parse(msg.slice(5)) as Data;
 
+        console.log(data);
         State.store.firstLaunch = false;
-        Settings.store.minimizeToTray = data.minimizeToTray;
-        Settings.store.discordBranch = data.discordBranch;
-        Settings.store.arRPC = data.richPresence;
         Settings.store.tray = true;
         Settings.store.trayColor = getAccentColor()?.slice(1);
+        Settings.store.minimizeToTray = !!data.minimizeToTray;
+        Settings.store.arRPC = !!data.richPresence;
 
         if (data.autoStart) autoStart.enable();
 
diff --git a/src/main/index.ts b/src/main/index.ts
index 29010c4..dbc0ee2 100644
--- a/src/main/index.ts
+++ b/src/main/index.ts
@@ -7,7 +7,7 @@
 import "./ipc";
 
 import { app, BrowserWindow, nativeTheme } from "electron";
-import { checkUpdates } from "updater/main";
+import { autoUpdater } from "electron-updater";
 
 import { DATA_DIR } from "./constants";
 import { createFirstLaunchTour } from "./firstLaunch";
@@ -21,6 +21,8 @@ if (IS_DEV) {
     require("source-map-support").install();
 }
 
+autoUpdater.checkForUpdatesAndNotify();
+
 // Make the Vencord files use our DATA_DIR
 process.env.VENCORD_USER_DATA_DIR = DATA_DIR;
 
@@ -74,7 +76,6 @@ function init() {
     });
 
     app.whenReady().then(async () => {
-        checkUpdates();
         if (process.platform === "win32") app.setAppUserModelId("dev.vencord.vesktop");
 
         registerScreenShareHandler();
diff --git a/src/main/ipc.ts b/src/main/ipc.ts
index 5c4fce6..0ba7c3a 100644
--- a/src/main/ipc.ts
+++ b/src/main/ipc.ts
@@ -29,6 +29,7 @@ import {
     pickTrayIcon,
     setTrayIcon
 } from "./tray";
+import { Settings, State } from "./settings";
 import { handle, handleSync } from "./utils/ipcWrappers";
 import { PopoutWindows } from "./utils/popout";
 import { isDeckGameMode, showGamePage } from "./utils/steamOS";
@@ -114,7 +115,14 @@ handle(IpcEvents.SPELLCHECK_ADD_TO_DICTIONARY, (e, word: string) => {
     e.sender.session.addWordToSpellCheckerDictionary(word);
 });
 
-handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
+handleSync(IpcEvents.GET_VENCORD_DIR, e => (e.returnValue = State.store.vencordDir));
+
+handle(IpcEvents.SELECT_VENCORD_DIR, async (_e, value?: null) => {
+    if (value === null) {
+        delete State.store.vencordDir;
+        return "ok";
+    }
+
     const res = await dialog.showOpenDialog(mainWin!, {
         properties: ["openDirectory"]
     });
@@ -123,7 +131,9 @@ handle(IpcEvents.SELECT_VENCORD_DIR, async () => {
     const dir = res.filePaths[0];
     if (!isValidVencordInstall(dir)) return "invalid";
 
-    return dir;
+    State.store.vencordDir = dir;
+
+    return "ok";
 });
 
 handle(IpcEvents.SET_BADGE_COUNT, (_, count: number) => setBadgeCount(count));
diff --git a/src/main/mainWindow.ts b/src/main/mainWindow.ts
index 6fe465c..639faec 100755
--- a/src/main/mainWindow.ts
+++ b/src/main/mainWindow.ts
@@ -94,7 +94,7 @@ function initTray(win: BrowserWindow) {
             click: createAboutWindow
         },
         {
-            label: "Update Vencord",
+            label: "Repair Vencord",
             async click() {
                 await downloadVencordFiles();
                 app.relaunch();
@@ -111,14 +111,14 @@ function initTray(win: BrowserWindow) {
             type: "separator"
         },
         {
-            label: "Relaunch",
+            label: "Restart",
             click() {
                 app.relaunch();
                 app.quit();
             }
         },
         {
-            label: "Quit Vesktop",
+            label: "Quit",
             click() {
                 isQuitting = true;
                 app.quit();
diff --git a/src/main/settings.ts b/src/main/settings.ts
index f2c1b80..b2aeea9 100644
--- a/src/main/settings.ts
+++ b/src/main/settings.ts
@@ -41,14 +41,7 @@ export const VencordSettings = loadSettings(VENCORD_SETTINGS_FILE, "Vencord
 if (Object.hasOwn(Settings.plain, "firstLaunch") && !existsSync(STATE_FILE)) {
     console.warn("legacy state in settings.json detected. migrating to state.json");
     const state = {} as TState;
-    for (const prop of [
-        "firstLaunch",
-        "maximized",
-        "minimized",
-        "skippedUpdate",
-        "steamOSLayoutVersion",
-        "windowBounds"
-    ] as const) {
+    for (const prop of ["firstLaunch", "maximized", "minimized", "steamOSLayoutVersion", "windowBounds"] as const) {
         state[prop] = Settings.plain[prop];
         delete Settings.plain[prop];
     }
diff --git a/src/main/utils/vencordLoader.ts b/src/main/utils/vencordLoader.ts
index 1bac37a..c0bac6a 100644
--- a/src/main/utils/vencordLoader.ts
+++ b/src/main/utils/vencordLoader.ts
@@ -4,7 +4,8 @@
  * Copyright (c) 2023 Vendicated and Vencord contributors
  */
 
-import { existsSync, mkdirSync } from "fs";
+import { mkdirSync } from "fs";
+import { access, constants as FsConstants } from "fs/promises";
 import { join } from "path";
 
 import { USER_AGENT, VENCORD_FILES_DIR } from "../constants";
@@ -56,12 +57,18 @@ export async function downloadVencordFiles() {
     );
 }
 
-export function isValidVencordInstall(dir: string) {
-    return FILES_TO_DOWNLOAD.every(f => existsSync(join(dir, f)));
+const existsAsync = (path: string) =>
+    access(path, FsConstants.F_OK)
+        .then(() => true)
+        .catch(() => false);
+
+export async function isValidVencordInstall(dir: string) {
+    return Promise.all(FILES_TO_DOWNLOAD.map(f => existsAsync(join(dir, f)))).then(arr => !arr.includes(false));
 }
 
 export async function ensureVencordFiles() {
-    if (isValidVencordInstall(VENCORD_FILES_DIR)) return;
+    if (await isValidVencordInstall(VENCORD_FILES_DIR)) return;
+
     mkdirSync(VENCORD_FILES_DIR, { recursive: true });
 
     await downloadVencordFiles();
diff --git a/src/preload/VesktopNative.ts b/src/preload/VesktopNative.ts
index d8a8c71..20cca15 100644
--- a/src/preload/VesktopNative.ts
+++ b/src/preload/VesktopNative.ts
@@ -7,7 +7,6 @@
 import { Node } from "@vencord/venmic";
 import { ipcRenderer } from "electron";
 import type { Settings } from "shared/settings";
-import type { LiteralUnion } from "type-fest";
 
 import { IpcEvents } from "../shared/IpcEvents";
 import { invoke, sendSync } from "./typedIpc";
@@ -37,7 +36,9 @@ export const VesktopNative = {
         showItemInFolder: (path: string) => invoke(IpcEvents.SHOW_ITEM_IN_FOLDER, path),
         selectVencordDir: () => invoke>(IpcEvents.SELECT_VENCORD_DIR),
         selectTrayIcon: (iconName: string) =>
-            invoke>(IpcEvents.SELECT_TRAY_ICON, iconName)
+            invoke>(IpcEvents.SELECT_TRAY_ICON, iconName),
+        getVencordDir: () => sendSync(IpcEvents.GET_VENCORD_DIR),
+        selectVencordDir: (value?: null) => invoke<"cancelled" | "invalid" | "ok">(IpcEvents.SELECT_VENCORD_DIR, value)
     },
     settings: {
         get: () => sendSync(IpcEvents.GET_SETTINGS),
diff --git a/src/renderer/components/ScreenSharePicker.tsx b/src/renderer/components/ScreenSharePicker.tsx
index e0cff77..c7403b9 100644
--- a/src/renderer/components/ScreenSharePicker.tsx
+++ b/src/renderer/components/ScreenSharePicker.tsx
@@ -721,7 +721,7 @@ function ModalComponent({
 
                                 const constraints = {
                                     ...track.getConstraints(),
-                                    frameRate,
+                                    frameRate: { min: frameRate, ideal: frameRate },
                                     width: { min: 640, ideal: width, max: width },
                                     height: { min: 480, ideal: height, max: height },
                                     advanced: [{ width: width, height: height }],
diff --git a/src/renderer/components/settings/Settings.tsx b/src/renderer/components/settings/Settings.tsx
index 00d0d81..0591dc6 100644
--- a/src/renderer/components/settings/Settings.tsx
+++ b/src/renderer/components/settings/Settings.tsx
@@ -102,15 +102,7 @@ const SettingsOptions: Record>
             defaultValue: false
         }
     ],
-    "Notifications & Updates": [
-        NotificationBadgeToggle,
-        {
-            key: "checkUpdates",
-            title: "Check for updates",
-            description: "Automatically check for Vesktop updates",
-            defaultValue: true
-        }
-    ],
+    Notifications: [NotificationBadgeToggle],
     Miscelleanous: [
         {
             key: "arRPC",
diff --git a/src/renderer/components/settings/VencordLocationPicker.tsx b/src/renderer/components/settings/VencordLocationPicker.tsx
index 3759ae2..9af4711 100644
--- a/src/renderer/components/settings/VencordLocationPicker.tsx
+++ b/src/renderer/components/settings/VencordLocationPicker.tsx
@@ -4,24 +4,28 @@
  * Copyright (c) 2023 Vendicated and Vencord contributors
  */
 
+import { useForceUpdater } from "@vencord/types/utils";
 import { Button, Forms, Toasts } from "@vencord/types/webpack/common";
 
 import { SettingsComponent } from "./Settings";
 
 export const VencordLocationPicker: SettingsComponent = ({ settings }) => {
+    const forceUpdate = useForceUpdater();
+    const vencordDir = VesktopNative.fileManager.getVencordDir();
+
     return (
         <>
             
                 Vencord files are loaded from{" "}
-                {settings.vencordDir ? (
+                {vencordDir ? (
                      {
                             e.preventDefault();
-                            VesktopNative.fileManager.showItemInFolder(settings.vencordDir!);
+                            VesktopNative.fileManager.showItemInFolder(vencordDir!);
                         }}
                     >
-                        {settings.vencordDir}
+                        {vencordDir}
                     
                 ) : (
                     "the default location"
@@ -34,7 +38,14 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => {
                         const choice = await VesktopNative.fileManager.selectVencordDir();
                         switch (choice) {
                             case "cancelled":
-                                return;
+                                break;
+                            case "ok":
+                                Toasts.show({
+                                    message: "Vencord install changed. Fully restart Vesktop to apply.",
+                                    id: Toasts.genId(),
+                                    type: Toasts.Type.SUCCESS
+                                });
+                                break;
                             case "invalid":
                                 Toasts.show({
                                     message:
@@ -42,9 +53,9 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => {
                                     id: Toasts.genId(),
                                     type: Toasts.Type.FAILURE
                                 });
-                                return;
+                                break;
                         }
-                        settings.vencordDir = choice;
+                        forceUpdate();
                     }}
                 >
                     Change
@@ -52,7 +63,10 @@ export const VencordLocationPicker: SettingsComponent = ({ settings }) => {
                 
diff --git a/src/renderer/fixes.css b/src/renderer/fixes.css
index aeec1bf..20e80aa 100644
--- a/src/renderer/fixes.css
+++ b/src/renderer/fixes.css
@@ -8,4 +8,9 @@
 * {
     scrollbar-width: unset !important;
     scrollbar-color: unset !important;
-}
\ No newline at end of file
+}
+
+/* Workaround for making things in the draggable area clickable again on macOS */
+.platform-osx [class*=topic_], .platform-osx [class*=notice_] button {
+    -webkit-app-region: no-drag;
+}
diff --git a/src/renderer/index.ts b/src/renderer/index.ts
index 99dca25..e8ad31c 100644
--- a/src/renderer/index.ts
+++ b/src/renderer/index.ts
@@ -13,7 +13,7 @@ console.log("read if cute :3");
 
 export * as Components from "./components";
 import { findByPropsLazy, onceReady } from "@vencord/types/webpack";
-import { FluxDispatcher } from "@vencord/types/webpack/common";
+import { Alerts, FluxDispatcher } from "@vencord/types/webpack/common";
 
 import SettingsUi from "./components/settings/Settings";
 import { Settings } from "./settings";
@@ -59,3 +59,19 @@ VesktopNative.arrpc.onActivity(async data => {
 
     arRPC.handleEvent(new MessageEvent("message", { data }));
 });
+
+// TODO: remove soon
+const vencordDir = "vencordDir" as keyof typeof Settings.store;
+if (Settings.store[vencordDir]) {
+    onceReady.then(() =>
+        setTimeout(
+            () =>
+                Alerts.show({
+                    title: "Custom Vencord Location",
+                    body: "Due to security hardening changes in Vesktop, your custom Vencord location had to be reset. Please configure it again in the settings.",
+                    onConfirm: () => delete Settings.store[vencordDir]
+                }),
+            5000
+        )
+    );
+}
diff --git a/src/renderer/patches/enableNotificationsByDefault.ts b/src/renderer/patches/enableNotificationsByDefault.ts
index f48115d..5854977 100644
--- a/src/renderer/patches/enableNotificationsByDefault.ts
+++ b/src/renderer/patches/enableNotificationsByDefault.ts
@@ -13,7 +13,7 @@ addPatch({
             replacement: {
                 // FIXME: fix eslint rule
                 // eslint-disable-next-line no-useless-escape
-                match: /\.isPlatformEmbedded(?=\?\i\.DesktopNotificationTypes\.ALL)/g,
+                match: /\.isPlatformEmbedded(?=\?\i\.\i\.ALL)/g,
                 replace: "$&||true"
             }
         }
diff --git a/src/renderer/patches/hideSwitchDevice.tsx b/src/renderer/patches/hideSwitchDevice.tsx
index 911aed7..20aa51a 100644
--- a/src/renderer/patches/hideSwitchDevice.tsx
+++ b/src/renderer/patches/hideSwitchDevice.tsx
@@ -12,7 +12,7 @@ addPatch({
             find: "lastOutputSystemDevice.justChanged",
             replacement: {
                 // eslint-disable-next-line no-useless-escape
-                match: /(\i)\.default\.getState\(\).neverShowModal/,
+                match: /(\i)\.\i\.getState\(\).neverShowModal/,
                 replace: "$& || $self.shouldIgnore($1)"
             }
         }
diff --git a/src/renderer/patches/screenShareFixes.ts b/src/renderer/patches/screenShareFixes.ts
index 66e4b14..00487d3 100644
--- a/src/renderer/patches/screenShareFixes.ts
+++ b/src/renderer/patches/screenShareFixes.ts
@@ -36,7 +36,7 @@ if (isLinux) {
 
         const constraints = {
             ...track.getConstraints(),
-            frameRate,
+            frameRate: { min: frameRate, ideal: frameRate },
             width: { min: 640, ideal: width, max: width },
             height: { min: 480, ideal: height, max: height },
             advanced: [{ width: width, height: height }],
diff --git a/src/shared/IpcEvents.ts b/src/shared/IpcEvents.ts
index 96eda30..bf08c24 100644
--- a/src/shared/IpcEvents.ts
+++ b/src/shared/IpcEvents.ts
@@ -23,6 +23,7 @@ export const enum IpcEvents {
     GET_SETTINGS = "VCD_GET_SETTINGS",
     SET_SETTINGS = "VCD_SET_SETTINGS",
 
+    GET_VENCORD_DIR = "VCD_GET_VENCORD_DIR",
     SELECT_VENCORD_DIR = "VCD_SELECT_VENCORD_DIR",
 
     UPDATER_GET_DATA = "VCD_UPDATER_GET_DATA",
diff --git a/src/shared/settings.d.ts b/src/shared/settings.d.ts
index 68ae6b9..f49e4ad 100644
--- a/src/shared/settings.d.ts
+++ b/src/shared/settings.d.ts
@@ -8,7 +8,6 @@ import type { Rectangle } from "electron";
 
 export interface Settings {
     discordBranch?: "stable" | "canary" | "ptb";
-    vencordDir?: string;
     transparencyOption?: "none" | "mica" | "tabbed" | "acrylic";
     tray?: boolean;
     trayColor?: string;
@@ -30,8 +29,6 @@ export interface Settings {
     clickTrayToShowHide?: boolean;
     customTitleBar?: boolean;
 
-    checkUpdates?: boolean;
-
     splashTheming?: boolean;
     splashColor?: string;
     splashBackground?: string;
@@ -57,8 +54,9 @@ export interface State {
     windowBounds?: Rectangle;
     displayid: int;
 
-    skippedUpdate?: string;
     firstLaunch?: boolean;
 
     steamOSLayoutVersion?: number;
+
+    vencordDir?: string;
 }
diff --git a/src/shared/utils/SettingsStore.ts b/src/shared/utils/SettingsStore.ts
index 22dd145..6aa7771 100644
--- a/src/shared/utils/SettingsStore.ts
+++ b/src/shared/utils/SettingsStore.ts
@@ -59,6 +59,19 @@ export class SettingsStore {
                 self.pathListeners.get(setPath)?.forEach(cb => cb(value));
 
                 return true;
+            },
+            deleteProperty(target, key: string) {
+                if (!(key in target)) return true;
+
+                const res = Reflect.deleteProperty(target, key);
+                if (!res) return false;
+
+                const setPath = `${path}${path && "."}${key}`;
+
+                self.globalListeners.forEach(cb => cb(root, setPath));
+                self.pathListeners.get(setPath)?.forEach(cb => cb(undefined));
+
+                return res;
             }
         });
     }
diff --git a/src/updater/main.ts b/src/updater/main.ts
deleted file mode 100644
index 4c19ffd..0000000
--- a/src/updater/main.ts
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-3.0
- * Vesktop, a desktop app aiming to give you a snappier Discord Experience
- * Copyright (c) 2023 Vendicated and Vencord contributors
- */
-
-import { app, BrowserWindow, shell } from "electron";
-import { PORTABLE } from "main/constants";
-import { Settings, State } from "main/settings";
-import { handle } from "main/utils/ipcWrappers";
-import { makeLinksOpenExternally } from "main/utils/makeLinksOpenExternally";
-import { githubGet, ReleaseData } from "main/utils/vencordLoader";
-import { join } from "path";
-import { IpcEvents } from "shared/IpcEvents";
-import { ICON_PATH, VIEW_DIR } from "shared/paths";
-
-export interface UpdateData {
-    currentVersion: string;
-    latestVersion: string;
-    release: ReleaseData;
-}
-
-let updateData: UpdateData;
-
-handle(IpcEvents.UPDATER_GET_DATA, () => updateData);
-handle(IpcEvents.UPDATER_DOWNLOAD, () => {
-    const { assets } = updateData.release;
-    const url = (() => {
-        switch (process.platform) {
-            case "win32":
-                return assets.find(a => {
-                    return a.name.endsWith(PORTABLE ? "win.zip" : ".exe");
-                })!.browser_download_url;
-            case "darwin":
-                return assets.find(a =>
-                    process.arch === "arm64"
-                        ? a.name.endsWith("-arm64-mac.zip")
-                        : a.name.endsWith("-mac.zip") && !a.name.includes("arm64")
-                )!.browser_download_url;
-            case "linux":
-                return updateData.release.html_url;
-            default:
-                throw new Error(`Unsupported platform: ${process.platform}`);
-        }
-    })();
-
-    shell.openExternal(url);
-});
-
-handle(IpcEvents.UPDATE_IGNORE, () => {
-    State.store.skippedUpdate = updateData.latestVersion;
-});
-
-function isOutdated(oldVersion: string, newVersion: string) {
-    const oldParts = oldVersion.split(".");
-    const newParts = newVersion.split(".");
-
-    if (oldParts.length !== newParts.length)
-        throw new Error(`Incompatible version strings (old: ${oldVersion}, new: ${newVersion})`);
-
-    for (let i = 0; i < oldParts.length; i++) {
-        const oldPart = Number(oldParts[i]);
-        const newPart = Number(newParts[i]);
-
-        if (isNaN(oldPart) || isNaN(newPart))
-            throw new Error(`Invalid version string (old: ${oldVersion}, new: ${newVersion})`);
-
-        if (oldPart < newPart) return true;
-        if (oldPart > newPart) return false;
-    }
-
-    return false;
-}
-
-export async function checkUpdates() {
-    if (Settings.store.checkUpdates === false) return;
-
-    try {
-        const raw = await githubGet("/repos/Vencord/Vesktop/releases/latest");
-        const data: ReleaseData = await raw.json();
-
-        const oldVersion = app.getVersion();
-        const newVersion = data.tag_name.replace(/^v/, "");
-        updateData = {
-            currentVersion: oldVersion,
-            latestVersion: newVersion,
-            release: data
-        };
-
-        if (State.store.skippedUpdate !== newVersion && isOutdated(oldVersion, newVersion)) {
-            openNewUpdateWindow();
-        }
-    } catch (e) {
-        console.error("AppUpdater: Failed to check for updates\n", e);
-    }
-}
-
-function openNewUpdateWindow() {
-    const win = new BrowserWindow({
-        width: 500,
-        autoHideMenuBar: true,
-        alwaysOnTop: true,
-        webPreferences: {
-            preload: join(__dirname, "updaterPreload.js"),
-            nodeIntegration: false,
-            contextIsolation: true,
-            sandbox: true
-        },
-        icon: ICON_PATH
-    });
-
-    makeLinksOpenExternally(win);
-
-    win.loadFile(join(VIEW_DIR, "updater.html"));
-}
diff --git a/src/updater/preload.ts b/src/updater/preload.ts
deleted file mode 100644
index 80e4dee..0000000
--- a/src/updater/preload.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * SPDX-License-Identifier: GPL-3.0
- * Vesktop, a desktop app aiming to give you a snappier Discord Experience
- * Copyright (c) 2023 Vendicated and Vencord contributors
- */
-
-import { contextBridge } from "electron";
-import { invoke } from "preload/typedIpc";
-import { IpcEvents } from "shared/IpcEvents";
-
-import type { UpdateData } from "./main";
-
-contextBridge.exposeInMainWorld("Updater", {
-    getData: () => invoke(IpcEvents.UPDATER_GET_DATA),
-    download: () => {
-        invoke(IpcEvents.UPDATER_DOWNLOAD);
-        invoke(IpcEvents.CLOSE);
-    },
-    ignore: () => invoke(IpcEvents.UPDATE_IGNORE),
-    close: () => invoke(IpcEvents.CLOSE)
-});