diff --git a/src/main/index.js b/src/main/index.js
index 2d0a536..d67f967 100644
--- a/src/main/index.js
+++ b/src/main/index.js
@@ -19,11 +19,12 @@ global.sendToRenderer = (event, data) => {
   global.win.webContents.send(event, serializeIpc(data))
 }
 
+const { autoUpdater } = require("electron-differential-updater")
+
 import path from "node:path"
 
 import { app, shell, BrowserWindow, ipcMain } from "electron"
 import { electronApp, optimizer, is } from "@electron-toolkit/utils"
-const { autoUpdater } = require("electron-differential-updater")
 
 import open from "open"
 
@@ -67,6 +68,14 @@ class ElectronApp {
     },
     "check:setup": async () => {
       return await setup()
+    },
+    "updater:check": () => {
+      autoUpdater.checkForUpdates()
+    },
+    "updater:apply": () => {
+      setTimeout(() => {
+        autoUpdater.quitAndInstall()
+      }, 3000)
     }
   }
 
@@ -130,6 +139,20 @@ class ElectronApp {
       optimizer.watchWindowShortcuts(window)
     })
 
+    autoUpdater.on("update-available", (ev, info) => {
+      console.log(info)
+    })
+
+    autoUpdater.on("error", (ev, err) => {
+      console.error(err)
+    })
+
+    autoUpdater.on("update-downloaded", (ev, info) => {
+      console.log(info)
+
+      this.sendToRender("update-available", info)
+    })
+
     this.createWindow()
 
     app.on("activate", () => {
@@ -144,39 +167,6 @@ class ElectronApp {
       }
     })
 
-    autoUpdater.on("update-available", (ev, info) => {
-      console.log(info)
-
-      this.sendToRender("new:message", {
-        message: `New update available, downloading...`,
-        type: "loading",
-      })
-    })
-
-    autoUpdater.on("error", (ev, err) => {
-      console.error(err)
-
-      this.sendToRender("new:message", {
-        message: "Failed to auto update...",
-        type: "error",
-      })
-    })
-
-    autoUpdater.on("update-downloaded", (ev, info) => {
-      console.log(info)
-
-      this.sendToRender("new:message", {
-        message: `Update downloaded, restarting...`,
-        type: "loading",
-      })
-    })
-
-    autoUpdater.on("update-downloaded", (ev, info) => {
-      setTimeout(() => {
-        autoUpdater.quitAndInstall()
-      }, 3000)
-    })
-
     autoUpdater.checkForUpdates()
   }
 }
diff --git a/src/renderer/src/App.jsx b/src/renderer/src/App.jsx
index 91640b7..d1398be 100644
--- a/src/renderer/src/App.jsx
+++ b/src/renderer/src/App.jsx
@@ -9,7 +9,7 @@ import getRootCssVar from "utils/getRootCssVar"
 
 import InstallationsManager from "pages/manager"
 
-import { MdFolder, MdSettings } from "react-icons/md"
+import { MdFolder, MdSettings, MdDownload } from "react-icons/md"
 
 import Icon from "../assets/icon.jsx"
 
@@ -44,6 +44,7 @@ class App extends React.Component {
     loading: true,
     pkg: null,
     initializing: false,
+    updateAvailable: true,
   }
 
   ipcEvents = {
@@ -68,10 +69,37 @@ class App extends React.Component {
       })
     },
     "new:message": (event, data) => {
-      antd.message[data.type || "info"]( data.message)
+      antd.message[data.type || "info"](data.message)
+    },
+    "update-available": (event, data) => {
+      this.setState({
+        updateAvailable: true,
+      })
+
+      console.log(data)
+
+      antd.Modal.confirm({
+        title: "Update Available",
+        content: <>
+          <p>
+            A new version of the application is available.
+          </p>
+        </>,
+        okText: "Update",
+        cancelText: "Later",
+        onOk: () => {
+          this.applyUpdate()
+        }
+      })
     }
   }
 
+  applyUpdate = () => {
+    antd.message.loading("Updating, please wait...")
+
+    ipc.exec("updater:apply")
+  }
+
   componentDidMount = async () => {
     for (const event in this.ipcEvents) {
       ipc.on(event, this.ipcEvents[event])
@@ -115,6 +143,16 @@ class App extends React.Component {
 
             {
               !loading && <div className="menu">
+                {
+                  this.state.updateAvailable && <antd.Button
+                    size="small"
+                    icon={<MdDownload />}
+                    onClick={this.applyUpdate}
+                  >
+                    Update now
+                  </antd.Button>
+                }
+
                 <antd.Button
                   size="small"
                   icon={<MdSettings />}