{"id":14062802,"url":"https://github.com/Aetherinox/ntfy-desktop","last_synced_at":"2025-07-29T14:31:35.168Z","repository":{"id":247307439,"uuid":"825493559","full_name":"Aetherinox/ntfy-desktop","owner":"Aetherinox","description":"Ntfy.sh desktop client for Windows, Linux, and MacOS with push notifications. Supports official ntfy.sh website and self-hosted instances.","archived":false,"fork":false,"pushed_at":"2025-07-18T05:15:18.000Z","size":3011,"stargazers_count":55,"open_issues_count":6,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-18T07:26:52.213Z","etag":null,"topics":["electron","javascript","javascript-application","nodejs","nodejs-application","ntfy","ntfy-sh","ntfysh","push-notifications","self-hosted","self-hosting"],"latest_commit_sha":null,"homepage":"https://ntfy.sh","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Aetherinox.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"custom":["https://buymeacoffee.com/aetherinox"],"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null}},"created_at":"2024-07-07T23:44:45.000Z","updated_at":"2025-07-18T05:15:21.000Z","dependencies_parsed_at":"2024-07-19T15:35:31.191Z","dependency_job_id":"6e816a5c-f51e-4213-a090-27b50510f6fa","html_url":"https://github.com/Aetherinox/ntfy-desktop","commit_stats":null,"previous_names":["aetherinox/ntfy-electron","aetherinox/ntfy-desktop"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/Aetherinox/ntfy-desktop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aetherinox%2Fntfy-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aetherinox%2Fntfy-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aetherinox%2Fntfy-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aetherinox%2Fntfy-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Aetherinox","download_url":"https://codeload.github.com/Aetherinox/ntfy-desktop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Aetherinox%2Fntfy-desktop/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267702991,"owners_count":24130463,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-29T02:00:12.549Z","response_time":2574,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["electron","javascript","javascript-application","nodejs","nodejs-application","ntfy","ntfy-sh","ntfysh","push-notifications","self-hosted","self-hosting"],"created_at":"2024-08-13T07:02:29.262Z","updated_at":"2025-07-29T14:31:35.156Z","avatar_url":"https://github.com/Aetherinox.png","language":"JavaScript","funding_links":["https://buymeacoffee.com/aetherinox"],"categories":["JavaScript"],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\u003ch6\u003eNtfy.sh desktop client for Windows, Linux, and MacOSX\u003c/h6\u003e\n\u003ch1\u003e♾️ ntfy-desktop ♾️\u003c/h1\u003e\n\n\u003cbr /\u003e\n\n\u003cp\u003eA ntfy.sh desktop client built with Electron which supports Windows, Linux, and MacOSX. This client rests in your taskbar tray and allows you to receive push notifications to your desktop without requiring you to leave your browser open.\u003c/p\u003e\n\n\u003cp float=\"left\"\u003e\n  \u003cimg style=\"padding-right:15px;\" src=\"https://github.com/user-attachments/assets/b6a34bc3-dbbf-4249-b3d2-d113a21cca66\" width=\"300\" /\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/4f842360-bc94-46eb-8660-17f221fe745d\" width=\"300\" /\u003e \n\u003c/p\u003e\n\n\u003cp float=\"left\"\u003e\n  \u003cimg style=\"padding-right:15px;\" src=\"https://github.com/user-attachments/assets/ebe0c02c-336f-4e95-b0f9-24c5b853f0e4\" width=\"300\" /\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/31c0a712-f596-44b1-a30d-fdbe579d9df6\" width=\"300\" /\u003e \n\u003c/p\u003e\n\n\u003cp float=\"left\"\u003e\n  \u003cimg style=\"padding-right:15px;\" src=\"https://github.com/user-attachments/assets/ce32d901-b35b-48e5-85b5-3cf82ae09b1e\" width=\"300\" /\u003e\n  \u003cimg src=\"https://github.com/user-attachments/assets/a04f6222-9a29-40c3-a2d2-82bd8f6f4c09\" width=\"300\" /\u003e \n\u003c/p\u003e\n\n\u003cbr /\u003e\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003c!-- prettier-ignore-start --\u003e\n[![Version][github-version-img]][github-version-uri]\n[![Build Status][github-build-img]][github-build-uri]\n[![Build Status][github-tests-img]][github-tests-uri]\n[![Downloads][github-downloads-img]][github-downloads-uri]\n[![Size][github-size-img]][github-size-img]\n[![Last Commit][github-commit-img]][github-commit-img]\n[![Contributors][contribs-all-img]](#contributors-)\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n- [About](#about)\n  - [What is Ntfy](#what-is-ntfy)\n  - [Ntfy Desktop Features](#ntfy-desktop-features)\n  - [Self-hosted vs Ntfy.sh](#self-hosted-vs-ntfysh)\n  - [Architecture Outline](#architecture-outline)\n- [Usage](#usage)\n  - [Key Binds](#key-binds)\n  - [CLI Arguments](#cli-arguments)\n- [Build](#build)\n  - [Method: Build Script](#method-build-script)\n    - [Windows](#windows)\n    - [Linux](#linux)\n    - [MacOSX](#macosx)\n  - [Method: Package.json Command](#method-packagejson-command)\n    - [Summary](#summary)\n    - [Windows](#windows-1)\n    - [Linux](#linux-1)\n    - [MacOSX](#macosx-1)\n- [Tests](#tests)\n  - [Github Workflow](#github-workflow)\n  - [Manual Test](#manual-test)\n    - [Playwright Tests](#playwright-tests)\n    - [Vitest Tests](#vitest-tests)\n- [Linting](#linting)\n- [Signed Releases](#signed-releases)\n  - [Validate .Sig](#validate-sig)\n  - [Validate SHA256SUM](#validate-sha256sum)\n  - [Validate SHA1SUM](#validate-sha1sum)\n- [Dependencies](#dependencies)\n- [Contributors ✨](#contributors-)\n\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# About\n\nThis project allows you to access the official free / paid notification service [ntfy.sh](https://ntfy.sh/), or your own self-hosted version of ntfy from within a desktop application which utilizes Electron as the wrapper.\n\n\u003cbr /\u003e\n\n## What is Ntfy\n\n[ntfy.sh](https://ntfy/) (pronounced \"notify\") is a simple HTTP-based pub-sub notification service. With [ntfy](https://ntfy/), you can send notifications to your phone or desktop via scripts from any computer, without having to sign up or pay any fees. If you'd like to run your own instance of the service, you can easily do so since ntfy is open source.\n\nTo install Ntfy on your system, visit the following links:\n\n\u003cdiv align=\"center\"\u003e\n\n[![View](https://img.shields.io/badge/%20-%20Download%20Ntfy.sh%20-%20%231F85DE?style=for-the-badge\u0026logo=github\u0026logoColor=FFFFFF)](https://github.com/binwiederhier/ntfy/releases) [![Download](https://img.shields.io/badge/%20-%20View%20Documentation-%20%23de2343?style=for-the-badge\u0026logo=github\u0026logoColor=FFFFFF)](https://docs.ntfy.sh/install/)\n\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n## Ntfy Desktop Features\n\n- Supports both the official ntfy.sh website / service or your own self-hosted instance\n  - To self-host, you must install Ntfy server on a local machine.\n  - View docs at https://docs.ntfy.sh/install/\n- Two modes for minimizing app, configure in settings\n  1. Close button exits app completely; OR\n  2. Close button sends app to tray. Right-click tray icon to quit / show app\n- Start app minimized\n- Shortcut key-binds\n  - Can disable the keyboard shortcuts\n- Receive push notifications from ntfy server to desktop\n  - Ability to adjust polling rate\n  - Modify `datetime` format\n  - Notifications (two options):\n    1. Persistent (sticky) notifications which require user interaction to clear\n    2. Timed notifications which disappear after X seconds\n  - Topic filtering \u0026 support\n    - Defaults: `news, announcements`\n- Supports Ntfy API token\n- Taskbar unread message count / count\n- Includes [command-line arguments](#cli-arguments)\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n## Self-hosted vs Ntfy.sh\n\nTo use this desktop client, you will be required to either have an Ntfy.sh account, or you must host your own instance of the Ntfy.sh server to pull notifications from. \n\nYou can install your own self-hosted copy of Ntfy server from:\n\n- https://github.com/binwiederhier/ntfy/releases\n\n\u003cbr /\u003e\n\nBe aware that the official [ntfy.sh](https://ntfy/) website will **rate-limit** users who have not purchased a paid package. Out of box, this ntfy-desktop client polls for new notifications every `30 seconds`; if you are on the free plan and decrease this timer in the desktop client settings, you will get an error saying that you have gone over your rate-limit. \n\n\u003cbr /\u003e\n\nIf you are self-hosting your own copy of Ntfy, you must open the Ntfy Desktop client, click the top menu item **App**, go down to **Settings** and then click **Instance**. You must set your instance URL to your personal self-hosted instance. To set your instance URL back to the official ntfy server, clear the URL box and save.\n\n\u003cp align=\"center\"\u003e\u003cimg style=\"width: 80%;text-align: center;\" src=\"docs/img/README/selfhost.gif\"\u003e\u003c/p\u003e\n\n\u003cbr /\u003e\n\nYou can set the polling rate lower without any limitations or rate limits:\n\n\u003cp align=\"center\"\u003e\u003cimg style=\"width: 80%;text-align: center;\" src=\"docs/img/README/polling.gif\"\u003e\u003c/p\u003e\n\n\u003cbr /\u003e\n\n## Architecture Outline\n\nWe provide numerous different architectures you can download this app for. Below is a list:\n\n\u003cbr /\u003e\n\n| Architecture | Bits | Devices / Examples                                             |\n| ------------ | ---- | -------------------------------------------------------------- |\n| **ARMv7l**   | 32   | Raspberry Pi 2 \u0026 3 (32-bit), Nexus 7, PS Vita (ARM Cortex-A9)  |\n| **ARMv6l**   | 32   | Raspberry Pi 1, Pi Zero, iPhone 3G                             |\n| **ARM64**    | 64   | Apple M1/M2/M3 Macs, Raspberry Pi 4 (64-bit OS), iPhone 5s+    |\n| **AMD64**    | 64   | Modern PCs, PS5, Xbox Series X, Steam Deck                     |\n| **I386**     | 32   | 386-era PCs, Windows 95 machines, Compaq Deskpro, old netbooks |\n| **IA32**     | 32   | Same as i386; Intel Atom netbooks, Pentium 4 PCs               |\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Usage\n\nThis section explains how to use ntfy-desktop once you have it ready to go on your system.\n\n\u003cbr /\u003e\n\n## Key Binds\nThe following keybinds can be used within ntfy-desktop:\n\n\u003cbr /\u003e\n\n| Key(s) | Description |\n| --- | --- |\n| `CTRL + R` | Refresh page |\n| `CTRL + Q` | Quit application |\n| `CTRL + M` | Minimize to tray |\n| `CTRL + =` | Zoom in |\n| `CTRL + -` | Zoom out |\n| `CTRL + 0` | Zoom reset |\n| `CTRL + SHIFT + I` | Developer tools |\n| `F12` | Developer tools |\n| `CTRL + G` | Show General settings window |\n| `CTRL + I` | Show URL / Instance window |\n| `CTRL + T` | Show API Token settings window |\n| `CTRL + SHIFT + T` | Show Topics settings window |\n| `CTRL + N` | Show Notifications settings window |\n\n\u003cbr /\u003e\n\n\u003e [!NOTE]\n\u003e Hotkeys are disabled by default. To enable hotkeys, select **App** in the top menu, and select **Settings** -\u003e **General**.\n\u003e \n\u003e Enable `Allow usage of hotkeys to navigate`\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n## CLI Arguments\n\nThis client allows you to utilize the following command-line arguments with ntfy-desktop:\n\n\u003cbr /\u003e\n\n| Argument | Description | Available as setting |\n| --- | --- | --- |\n| `--hidden` | Start app hidden in tray, suitable for auto-starting on system login/boot | ✅ |\n| `--hotkey` | Start app with hotkeys enabled | ✅ |\n| `--quit` | Top-right close button will completely exit app instead of minimize to tray | ✅ |\n| `--devtools` | Start app with developer tools in `App` menu | ✅ |\n| `--env \u003cenv_name\u003e` | Define startup environment | ❌ |\n\n\u003cbr /\u003e\n\nIf you are running ntfy-desktop from node, you can pass arguments using the following example:\n\n```shell ignore\nnpm run start -- --hidden --hotkey\n```\n\n\u003cbr /\u003e\n\nIf using the pre-built binaries, pass arguments by opening your terminal / command prompt, and passing the arguments using:\n\n```shell\n# Windows\nntfy-desktop-win32-x64/ntfy-desktop.exe --hidden --hotkey\n\n# Linux\nntfy-desktop-linux-x64/ntfy-desktop --hidden --hotkey\n\n# MacOS\nntfy-desktop-darwin-x64/ntfy-desktop.app/Contents/MacOS/ntfy-desktop --hidden --hotkey\n```\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Build\n\nThere are numerous ways to build this application. \n\n\u003cbr /\u003e\n\n## Method: Build Script\n\nThis method makes use of the `build.bat` and `build.sh` scripts provided in this repository. Find your operating system below and follow the instructions:\n\n- [Windows](#windows)\n- [Linux](#linux)\n- [MacOSX](#macosx)\n\n\u003cbr /\u003e\n\n### Windows\n\nInstall NodeJS with NPM by going to the following URL. Make sure to select your current operating system at the top:\n\n- https://nodejs.org/en/download\n\n\u003cbr /\u003e\n\nNext, run the following commands in Powershell or Windows Command Prompt:\n\n```shell\n# Clone ntfy-desktop repo, make sure you are in an EMPTY folder:\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron\n\n# build ntfy\n./build.bat\n```\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n### Linux\n\nRun the following commands to install NodeJS + NPM, and then Ntfy Desktop:\n\n```shell\n# Install packages\nsudo apt update\nsudo apt install git nodejs npm wine64\n\n# create the needed folders\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\n\n# clone repo\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron-packager\n\n# set wine symlink\nsudo ln -s /usr/bin/wine /usr/bin/wine64\n\n# change permissions\nsudo chmod +x build.sh\n\n# build ntfy\n./build.sh\n```\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n### MacOSX\n\nInstall NodeJS with NPM by going to the following URL. Make sure to select your current operating system at the top.\n\n\u003cbr /\u003e\n\nTo install **node / npm**, download from:\n- https://nodejs.org/en/download\n\n\u003cbr /\u003e\n\nTo install **Git** on your system:\n\n- https://git-scm.com/downloads/mac\n\n\u003cbr /\u003e\n\nOpen your Terminal app and run the following commands:\n\n\u003cbr /\u003e\n\n```shell\n# install git\nbrew install git\n\n# install wine\nbrew install --cask wine-stable\n\n# create the needed folders\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\n\n# clone repo\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron-packager\n\n# set wine symlink\nsudo ln -s /usr/bin/wine /usr/bin/wine64\n\n# change permissions\nsudo chmod +x build.sh\n\n# build ntfy\n./build.sh\n```\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n## Method: Package.json Command\n\nYou can also build your own copy of ntfy-desktop by executing the included `package.json` run commands.\n\n- [Windows](#windows-1)\n- [Linux](#linux-1)\n- [MacOSX](#macosx-1)\n\n\u003cbr /\u003e\n\n### Summary\n\nTo run the `npm` commands, you must install NodeJS and NPM on your system. To install them, visit: \n\n- https://nodejs.org/en/download\n\n\u003cbr /\u003e\n\nThe `package.json` includes the commands listed below. Because the build commands have dynamic variables; you must run the command based on what operating system you are building from.\n\nIf you are building ntfy-desktop from a **Windows** machine:\n\n- `npm run build:win:windows`\n- `npm run build:win:linux`\n- `npm run build:win:mac`\n\n\u003cbr /\u003e\n\nIf you are building ntfy-desktop from a **Linux** or **MacOS** machine:\n\n- `npm run build:lin:windows`\n- `npm run build:lin:linux`\n- `npm run build:lin:mac`\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n### Windows\n\nInstall NodeJS with NPM by going to the following URL. Make sure to select your current operating system at the top:\n\n- https://nodejs.org/en/download\n\n\u003cbr /\u003e\n\nNext, run the following commands in Powershell or Windows Command Prompt:\n\n```shell\n# create the needed folders\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\n\n# clone repo\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron-packager\n\n# build ntfy-desktop from Windows to Windows machine\nnpm run build:win:windows\n\n# build ntfy-desktop from Windows to Linux machine\nnpm run build:lin:windows\n```\n\n\u003cbr \u003e\n\u003cbr \u003e\n\n### Linux\n\nRun the following commands to install NodeJS + NPM, and then Ntfy Desktop:\n\n```shell\n# Install NodeJS and NPM\nsudo apt update\nsudo apt install git nodejs npm wine64\n\n# create the needed folders\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\n\n# clone repo\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron-packager\n\n# set wine symlink\nsudo ln -s /usr/bin/wine /usr/bin/wine64\n\n# build ntfy-desktop from Linux to Windows machine\nnpm run build:lin:linux\n\n# build ntfy-desktop from Linux to Linux machine\nnpm run build:lin:windows\n```\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n### MacOSX\n\nInstall NodeJS with NPM by going to the following URL. Make sure to select your current operating system at the top:\n\n- https://nodejs.org/en/download\n\n\u003cbr /\u003e\n\nInstall **Git** on your system next:\n\n- https://git-scm.com/downloads/mac\n\n\u003cbr /\u003e\n\nOpen your Terminal app and run the following commands:\n\n```shell\n# Install NodeJS and NPM\nsudo apt update\nsudo apt install git nodejs npm wine64\n\n# create the needed folders\nmkdir ntfy-desktop \u0026\u0026 cd ntfy-desktop/\n\n# clone repo\ngit clone https://github.com/aetherinox/ntfy-desktop.git .\n\n# install npm packages\nnpm install\nnpm install -g electron-packager\n\n# set wine symlink\nsudo ln -s /usr/bin/wine /usr/bin/wine64\n\n# build ntfy-desktop from Windows to MacOS machine\nnpm run build:win:mac\n\n# build ntfy-desktop from Linux toL MacOS machine\nnpm run build:lin:mac\n```\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Tests\n\nThis repository contains tests in order to test the functionality of this project. We utilize a Github workflow to handle the automation, however, you can run the tests locally.\n\n\u003cbr /\u003e\n\nIn order to run these tests, you must have some dependencies installed on your system or runner:\n\n```shell\nsudo apt install xvfb -y\nnpm install\nnpx playwright install-deps\n```\n\n\u003cbr /\u003e\n\nIf you do not run the command `playwright install-deps`; then you will need to install all of the dependencies manually with the command:\n\n```shell\nsudo apt install xvfb -y\nsudo apt-get install libasound2 libxslt-dev woff2 libevent-dev libopus0 \\\n  libopus-dev libwebpdemux2 libharfbuzz-dev libharfbuzz0b libwebp-dev \\\n  libenchant-2-dev libsecret-1-0 libsecret-1-dev libglib2.0-dev libhyphen0 \\\n  libglfw3-dev libgles2-mesa-dev libudev1 libevdev2 libgles2-mesa yasm \\\n  libudev1 libudev-dev libgudev-1.0-0 libx264-dev libgconf-2-4 libatk1.0-0 \\\n  libatk-bridge2.0-0 libgdk-pixbuf2.0-0 libgtk-3-0 libgbm-dev libnss3-dev \\\n  libxss-dev -y\nnpx playwright install\n```\n\n\u003cbr /\u003e\n\n## Github Workflow\n\nYou can fork this repository and run the included Github workflows\n- https://github.com/Aetherinox/ntfy-desktop/blob/f794bb835cb68a2b6da74d9161e7432c673179ea/.github/workflows/npm-tests.yml\n\n\u003cbr /\u003e\n\nIn order for the workflow to work, your Github or self-hosted runner must have numerous dependencies installed. Ensure you do not remove the `npm install` and `apt install` commands from the workflow; otherwise the tests will fail.\n\n\u003cbr /\u003e\n\n## Manual Test\n\nYou can also run the included tests manually without a Github workflow with the instructions below.\n\n\u003cbr /\u003e\n\n### Playwright Tests\n\nThese tests specifically check the Electron app itself. They will attempt to open ntfy-desktop and make sure the application is in working order. These tests do NOT test the back-end code of the app. \n\n```shell\ncd ./src\nnpm run test\n```\n\n\u003cbr /\u003e\n\nYou should see numerous windows open and multiple copies of Ntfy Desktop start up. This is normal, and is the test checking out the functionality of the application.\n\n\u003cbr /\u003e\n\nIf you want to run the tests from a CI without having a GUI available to see the tests; you can run the command:\n\n```shell\nxvfb-run --auto-servernum \\\n  --server-args=\"-screen 0 1280x960x24\" npx playwright test \\\n  --trace on\n```\n\n\u003cbr /\u003e\n\nIf you want to run the tests, while having Electron running in debug / verbose mode; run the command:\n\n```shell\nDISPLAY=:0 DEBUG=pw:browser xvfb-run \\\n  --auto-servernum \\\n  --server-args=\"-screen 0 1280x960x24\" npx playwright test \\\n  --trace on\n```\n\n\u003cbr /\u003e\n\nThe tests should show something similar to the following:\n\n```console\n[chromium] › tests/main.spec.js:65:1 › ✅ ensure interface can fully load\n✅ Open New Window: About\n[webkit] › tests/main.spec.js:65:1 › ✅ ensure interface can fully load\n✅ Open New Window: About\n[chromium] › tests/main.spec.js:65:1 › ✅ ensure interface can fully load\n✅ Saved screenshot: test-results/fullload_1749458422355.png\n[webkit] › tests/main.spec.js:65:1 › ✅ ensure interface can fully load\n[SubscriptionManager] No browser subscription currently exists, so web push was never enabled or the notification permission was removed. Skipping.\n✅ Saved screenshot: test-results/fullload_1749458422373.png\n[firefox] › tests/main.spec.js:143:1 › ✅ fail to sign into invalid account\nntfy\n[chromium] › tests/main.spec.js:143:1 › ✅ fail to sign into invalid account\nntfy\n[webkit] › tests/main.spec.js:143:1 › ✅ fail to sign into invalid account\nntfy\n  9 passed (15.3s)\n\nTo open last HTML report run:\n\n  npx playwright show-report\n```\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n### Vitest Tests\n\nThese tests check the back-end functionality of the app, including a lot of the functions that the source code comes with.\n\n```shell\ncd ./src\nnpm run test:unit:run\n```\n\n\u003cbr /\u003e\n\nThe results for the tests will be printed in your terminal / command prompt.\n\n```shell\n RUN  v3.2.4 ntfy-desktop/src\n\n ✓ tests/storage.test.js (23 tests) 17ms\n ✓ tests/utils.test.js (26 tests) 31ms\n ✓ tests/logging.test.js (8 tests) 28ms\n\n Test Files  3 passed (3)\n      Tests  57 passed (57)\n   Start at  10:19:17\n   Duration  577ms (transform 158ms, setup 0ms, collect 427ms, tests 76ms, environment 1ms, prepare 377ms)\n```\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Linting\n\nThis node package comes with ESlint, and a set of rules which should be followed. If you have intentions of creating new features and contributing to this repository; you must follow these linter rules. You can check the current status of your code by running:\n\n```shell\ncd ./src\nnpm run lint\n```\n\n\u003cbr /\u003e\n\nAny failures will be reported in console:\n\n```shell\nntfy-desktop\\src\\tests\\storage.test.js\n    1:74   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    2:21   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    3:25   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    4:21   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    5:32   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    6:1    error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    7:3    error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    8:29   error  Expected linebreaks to be 'LF' but found 'CRLF'  @stylistic/linebreak-style\n    6:14   error  A space is required after '['                    @stylistic/array-bracket-spacing\n    6:29   error  A space is required before ']'                   @stylistic/array-bracket-spacing\n```\n\n\u003cbr /\u003e\n\nYou must fix these before submitting a contribution. You can opt to automatically fix errors by running the command:\n\n```shell\nnpm run lint:fix\n```\n\n\u003cbr /\u003e\n\n\u003e [!WARNING]\n\u003e Opting to automatically fix linting errors may result in mis-aligned brackets. Make sure these are fixed before submitting any pull requests.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Signed Releases\n\nThese steps allow you to validate the files `sha256sum.txt.asc`, `sha1sum.txt.asc`, and `sha256sum.sig` which we provide with every release.\n\nValidating these files helps ensure that the actual .zip or binary files you have downloaded indeed came from the real developer. Before you start reading the sections below; ensure you have the following packages installed:\n\n- GPG\n- sha1sum\n- sha256sum\n\n\u003cbr /\u003e\n\nYou can install these by running the commands:\n\n```shell\n# Ubuntu / Debian Systems\nsudo apt update\nsudo apt install gpg gnupg sha1sum sha256sum\n\n# Fedora / Redhat\n(yum | or | dnf ) install gpg gnupg\n```\n\n\u003cbr /\u003e\n\n## Validate .Sig\n\nEach release includes two `.sig` files; these are known as a GPG **Detached Signature**.\n\n- sha1sum.sig\n- sha256sum.sig\n\n\u003cbr /\u003e\n\nTo validate that these signatures are good, download each of the files to your local machine:\n\n```shell\n# sha1sum\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha1sum.sig\n\n# sha256sum\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha256sum.sig\n```\n\n\u003cbr /\u003e\n\nNext, you will need the two associated files:\n\n- sha1sum.txt.asc\n- sha256sum.txt.asc\n\n\u003cbr /\u003e\n\nTo download these, run the commands:\n\n```shell\n# sha1sum.txt.asc\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha1sum.txt.asc\n\n# sha256sum.txt.asc\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha256sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nNow we can validate that these files indeed came from the original developer; run the command:\n\n```shell\ngpg --verify sha1sum.sig sha1sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see the output:\n\n```shell\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [unknown]\nPrimary key fingerprint: E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\n     Subkey fingerprint: 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\n```\n\n\u003cbr /\u003e\n\nNow validate the `sha256sum.sig` with the `sha256sum.txt.asc`:\n\n```shell\ngpg --verify sha256sum.sig sha256sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see the output:\n\n```shell\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [unknown]\nPrimary key fingerprint: E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\n     Subkey fingerprint: 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\n```\n\n\u003cbr /\u003e\n\nIf you get the above results; you have validated the signature files.\n\n\u003cbr /\u003e\n\n\u003cbr /\u003e\n\n## Validate SHA256SUM\n\nThis section explains how you can validate the downloaded `.zip` files and see if they are indeed authentic from the original developer. Before you can validate these files, you need to download the public GPG key we use when we sign releases. You can download it by running the following command:\n\n```shell\ncurl -s https://github.com/BinaryServ.gpg | gpg --import\n```\n\n\u003cbr /\u003e\n\nDownload the `sha256sum.txt.asc` and validate the file itself:\n\n```shell\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha256sum.txt.asc\n\ngpg --verify sha256sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see the following. The value `6921C2D3F6AE1188B7721C72F397BC89486A29A6` is the key's fingerprint.\n\n```shell\ngpg: Signature made Mon 01 Jun 2025 00:00:00 UTC\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [ultimate]\n```\n\n\u003cbr /\u003e\n\nYou can view your existing GPG key fingerprints by running:\n\n```shell\ngpg --list-keys --keyid-format=long --fingerprint --with-fingerprint\n```\n\n\u003cbr /\u003e\n\nThis will allow you to see where the `692XXXXX` value comes from:\n\n```shell\npub   rsa4096 2025-04-21 [C]\n      E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\nuid           [ unknown] Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\nsub   rsa4096 2025-04-21 [S]\n \u003e\u003e\u003e\u003e 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\nsub   rsa4096 2025-04-21 [E]\n      25E9 AFEC C12F 2072 AA6E  D5AB B077 63D0 A12F 0ED8\nsub   rsa4096 2025-04-21 [A]\n      AD79 A1EA CE17 962F B4ED  B30A DBA8 EA76 62FC 54E2\n```\n\n\u003cbr /\u003e\n\nNext, download the `sha256sum.sig`\n\n```shell\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha256sum.sig\n```\n\n\u003cbr /\u003e\n\nTo validate the `.sig` file and your `sha256sum` file, run the command:\n\n```shell\ngpg --verify sha256sum.sig sha256sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see:\n\n```shell\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [unknown]\nPrimary key fingerprint: E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\n     Subkey fingerprint: 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\n```\n\n\u003cbr /\u003e\n\nYou can now validate the `sha256sum.txt.asc` file against the files you have downloaded from our repository. In order to verify that the files are legit, you must download them from the [Releases](https://github.com/Aetherinox/ntfy-desktop/releases) page. They end with the extension `.zip`. You can also download them using `wget`. Make sure you download the zip files to the same folder where you downloaded the `sha256sum.txt.asc` and `sha256sum.sig`\n\n```shell\n# Download ntfy-desktop-2.1.1-darwin-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-darwin-amd64.zip\n\n# Download ntfy-desktop-2.1.1-darwin-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-darwin-arm64.zip\n\n# Download ntfy-desktop-2.1.1-linux-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-amd64.zip\n\n# Download ntfy-desktop-2.1.1-linux-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-arm64.zip\n\n# Download ntfy-desktop-2.1.1-linux-armv7l.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-armv7l.zip\n\n# Download ntfy-desktop-2.1.1-win32-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-amd64.zip\n\n# Download ntfy-desktop-2.1.1-win32-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-arm64.zip\n\n# Download ntfy-desktop-2.1.1-win32-ia32.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-ia32.zip\n```\n\n\u003cbr /\u003e\n\nNext, extract the hashes from the hash digest `sha256sum.txt.asc` file by running the command:\n\n```shell\ngpg --output sha256sum.txt --verify sha256sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nThe command above will create a new file called `sha256sum.txt`, now run that file with the program `sha256sum`:\n\n```shell\nsha256sum --check sha256sum.txt\n```\n\n\u003cbr /\u003e\n\nWhich will output:\n\n```shell\n# Successful validation\nntfy-desktop-2.1.1-win32-ia32.zip: OK\nntfy-desktop-2.1.1-darwin-amd64.zip: OK\nntfy-desktop-2.1.1-win32-amd64.zip: OK\nntfy-desktop-2.1.1-win32-arm64.zip: OK\nntfy-desktop-2.1.1-darwin-arm64.zip: OK\nntfy-desktop-2.1.1-linux-armv7l.zip: OK\nntfy-desktop-2.1.1-linux-amd64.zip: OK\nntfy-desktop-2.1.1-linux-arm64.zip: OK\n\n# Files missing for validation\nntfy-desktop-2.1.1-linux-arm64.zip: FAILED open or read\n\n# File did not pass validation\nntfy-desktop-2.1.1-linux-arm64.zip: FAILED\n```\n\n\u003cbr /\u003e\n\nIf you see `FAILED` and the files are indeed there, ensure you downloaded them from our repository and not somewhere else.\n\n\u003cbr /\u003e\n\nIf you see `OK`; this means the files are valid.\n\n\u003cbr /\u003e\n\n## Validate SHA1SUM\n\nThis section explains how you can validate the downloaded `.zip` files and see if they are indeed authentic from the original developer. Validating the `sha1sum.txt.asc` is similar to the `sha256sum.txt.asc`, first, download the public GPG key we use when we sign releases. You can download it by running the following command:\n\n```shell\ncurl -s https://github.com/BinaryServ.gpg | gpg --import\n```\n\n\u003cbr /\u003e\n\nNext, download the `sha1sum.txt.asc` file:\n\n```shell\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha1sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nNow verify that the `sha1sum.txt.asc` is properly signed:\n\n```shell\ngpg --verify sha1sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see the following. The value `6921C2D3F6AE1188B7721C72F397BC89486A29A6` is the key's fingerprint.\n\n```shell\ngpg: Signature made Mon 01 Jun 2025 00:00:00 UTC\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [ultimate]\n```\n\n\u003cbr /\u003e\n\nYou can view your existing GPG key fingerprints by running:\n\n```shell\ngpg --list-keys --keyid-format=long --fingerprint --with-fingerprint\n```\n\n\u003cbr /\u003e\n\nThis will allow you to see where the `692XXXXX` value comes from:\n\n```shell\npub   rsa4096 2025-04-21 [C]\n      E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\nuid           [ unknown] Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\nsub   rsa4096 2025-04-21 [S]\n \u003e\u003e\u003e\u003e 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\nsub   rsa4096 2025-04-21 [E]\n      25E9 AFEC C12F 2072 AA6E  D5AB B077 63D0 A12F 0ED8\nsub   rsa4096 2025-04-21 [A]\n      AD79 A1EA CE17 962F B4ED  B30A DBA8 EA76 62FC 54E2\n```\n\n\u003cbr /\u003e\n\nNext, download the `sha1sum.sig`\n\n```shell\nwget https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/sha1sum.sig\n```\n\n\u003cbr /\u003e\n\nTo validate the `sha1sum.sig` file and your `sha1sum.txt.asc` file, run the command:\n\n```shell\ngpg --verify sha1sum.sig sha1sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nYou should see:\n\n```shell\ngpg:                using RSA key 6921C2D3F6AE1188B7721C72F397BC89486A29A6\ngpg: Good signature from \"Binary Ninja (RSA 4096) \u003cthebinaryninja@proton.me\u003e\" [unknown]\nPrimary key fingerprint: E8BA 8C94 B334 1673 0D8C  05C2 5769 7A1C BA63 B9FE\n     Subkey fingerprint: 6921 C2D3 F6AE 1188 B772  1C72 F397 BC89 486A 29A6\n```\n\n\u003cbr /\u003e\n\nYou can now validate the `sha1sum.txt.asc` file against the files you have downloaded from our repository. In order to verify that the files are legit, you must download them from the [Releases](https://github.com/Aetherinox/ntfy-desktop/releases) page. They end with the extension `.zip`. You can also download them using `wget`. Make sure you download the zip files to the same folder where you downloaded the `sha1sum.txt.asc` and `sha1sum.sig`\n\n```shell\n# Download ntfy-desktop-2.1.1-darwin-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-darwin-amd64.zip\n\n# Download ntfy-desktop-2.1.1-darwin-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-darwin-arm64.zip\n\n# Download ntfy-desktop-2.1.1-linux-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-amd64.zip\n\n# Download ntfy-desktop-2.1.1-linux-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-arm64.zip\n\n# Download ntfy-desktop-2.1.1-linux-armv7l.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-linux-armv7l.zip\n\n# Download ntfy-desktop-2.1.1-win32-amd64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-amd64.zip\n\n# Download ntfy-desktop-2.1.1-win32-arm64.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-arm64.zip\n\n# Download ntfy-desktop-2.1.1-win32-ia32.zip\nwget \\\n  https://github.com/Aetherinox/ntfy-desktop/releases/download/2.1.1/ntfy-desktop-2.1.1-win32-ia32.zip\n```\n\n\u003cbr /\u003e\n\nNext, extract the hashes from the hash digest `sha1sum.txt.asc` file by running the command:\n\n```shell\ngpg --output sha1sum.txt --verify sha1sum.txt.asc\n```\n\n\u003cbr /\u003e\n\nThe command above will create a new file called `sha1sum.txt`, now run that file with the program `sha1sum`:\n\n```shell\nsha1sum --check sha1sum.txt\n```\n\n\u003cbr /\u003e\n\nWhich will output:\n\n```shell\n# Successful validation\nntfy-desktop-2.1.1-win32-ia32.zip: OK\nntfy-desktop-2.1.1-darwin-amd64.zip: OK\nntfy-desktop-2.1.1-win32-amd64.zip: OK\nntfy-desktop-2.1.1-win32-arm64.zip: OK\nntfy-desktop-2.1.1-darwin-arm64.zip: OK\nntfy-desktop-2.1.1-linux-armv7l.zip: OK\nntfy-desktop-2.1.1-linux-amd64.zip: OK\nntfy-desktop-2.1.1-linux-arm64.zip: OK\n\n# Files missing for validation\nntfy-desktop-2.1.1-linux-arm64.zip: FAILED open or read\n\n# File did not pass validation\nntfy-desktop-2.1.1-linux-arm64.zip: FAILED\n```\n\n\u003cbr /\u003e\n\nIf you see `FAILED` and the files are indeed there, ensure you downloaded them from our repository and not somewhere else.\n\n\u003cbr /\u003e\n\nIf you see `OK`; this means the files are valid.\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Dependencies\n\nNtfy Desktop relies on the following packages, some of these are also made by us:\n\n\u003cbr /\u003e\n\n| Package | Language | Version | Description\n| --- | --- | --- | --- |\n| [ntfy-toast](https://github.com/Aetherinox/ntfy-toast) | C++ | [![Version][ntfy-toast-github-version-img]][ntfy-toast-github-version-uri] | Command-line application which handles toast notifications on Windows 8 and newer |\n| [toasted-notifier](https://github.com/Aetherinox/node-toasted-notifier) | Javascript | [![Version][toasted-notifier-npm-version-img]][toasted-notifier-npm-version-uri] | Node package which acts as a wrapper to send notification data between [Ntfy Desktop](https://github.com/Aetherinox/ntfy-desktop) and [ntfy-toast](https://github.com/Aetherinox/ntfy-toast) |\n| [electron-plugin-prompts](https://github.com/Aetherinox/node-electron-plugin-prompts) | Javascript | [![Version][plugin-prompts-npm-version-img]][plugin-prompts-npm-version-uri] | Node package which allows for more detailed and customizable interface forms |\n\n\n\u003cbr /\u003e\n\n---\n\n\u003cbr /\u003e\n\n# Contributors ✨\n\nWe are always looking for contributors. If you feel that you can provide something useful to this project, then we'd love to review your suggestion. Before submitting your contribution, please review the following resources:\n\n- [Pull Request Procedure](.github/PULL_REQUEST_TEMPLATE.md)\n- [Contributor Policy](CONTRIBUTING.md)\n\n\u003cbr /\u003e\n\nWant to help but can't write code?\n\n- Review [active questions by our community](https://github.com/aetherinox/ntfy-desktop/labels/❔%20Question) and answer the ones you know.\n\n\u003cbr /\u003e\n\n![Alt](https://repobeats.axiom.co/api/embed/09d6197df261c2b4521ddb0f2560f78ed2811a0d.svg \"Repobeats\")\n\n\u003cbr /\u003e\n\nThe following people have helped get this project going:\n\n\n\u003cbr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![Contributors][contribs-all-img]](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\"\u003e\u003ca href=\"https://github.com/aetherinox\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/118329232?v=4\u0026s=40\" width=\"80px;\" alt=\"Aetherinox\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAetherinox\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/aetherinox/noxenv/commits?author=aetherinox\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"#projectManagement-aetherinox\" title=\"Project Management\"\u003e📆\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/div\u003e\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\n\u003c!-- (electron-plugin-prompts \u003e BADGE \u003e VERSION \u003e NPMJS --\u003e\n  [plugin-prompts-npm-version-img]: https://img.shields.io/npm/v/electron-plugin-prompts?logo=npm\u0026label=Version\u0026color=ba5225\n  [plugin-prompts-npm-version-uri]: https://npmjs.com/package/electron-plugin-prompts\n\n\u003c!-- (toasted-notifier \u003e BADGE \u003e VERSION \u003e NPMJS --\u003e\n  [toasted-notifier-npm-version-img]: https://img.shields.io/npm/v/toasted-notifier?logo=npm\u0026label=Version\u0026color=ba5225\n  [toasted-notifier-npm-version-uri]: https://npmjs.com/package/toasted-notifier\n\n\u003c!-- ntfy-toastBADGE \u003e VERSION \u003e GITHUB --\u003e\n  [ntfy-toast-github-version-img]: https://img.shields.io/github/v/tag/aetherinox/ntfy-toast?logo=GitHub\u0026label=Version\u0026color=ba5225\n  [ntfy-toast-github-version-uri]: https://github.com/aetherinox/ntfy-toast/releases\n\n\n\n\n\u003c!-- BADGE \u003e GENERAL --\u003e\n  [general-npmjs-uri]: https://npmjs.com\n  [general-nodejs-uri]: https://nodejs.org\n  [general-npmtrends-uri]: http://npmtrends.com/ntfy-desktop\n\n\u003c!-- BADGE \u003e VERSION \u003e GITHUB --\u003e\n  [github-version-img]: https://img.shields.io/github/v/tag/aetherinox/ntfy-desktop?logo=GitHub\u0026label=Version\u0026color=ba5225\n  [github-version-uri]: https://github.com/aetherinox/ntfy-desktop/releases\n\n\u003c!-- BADGE \u003e VERSION \u003e NPMJS --\u003e\n  [npm-version-img]: https://img.shields.io/npm/v/ntfy-desktop?logo=npm\u0026label=Version\u0026color=ba5225\n  [npm-version-uri]: https://npmjs.com/package/ntfy-desktop\n\n\u003c!-- BADGE \u003e VERSION \u003e PYPI --\u003e\n  [pypi-version-img]: https://img.shields.io/pypi/v/ntfy-desktop\n  [pypi-version-uri]: https://pypi.org/project/ntfy-desktop/\n\n\u003c!-- BADGE \u003e LICENSE \u003e MIT --\u003e\n  [license-mit-img]: https://img.shields.io/badge/MIT-FFF?logo=creativecommons\u0026logoColor=FFFFFF\u0026label=License\u0026color=9d29a0\n  [license-mit-uri]: https://github.com/aetherinox/ntfy-desktop/blob/main/LICENSE\n\n\u003c!-- BADGE \u003e GITHUB \u003e DOWNLOAD COUNT --\u003e\n  [github-downloads-img]: https://img.shields.io/github/downloads/aetherinox/ntfy-desktop/total?logo=github\u0026logoColor=FFFFFF\u0026label=Downloads\u0026color=376892\n  [github-downloads-uri]: https://github.com/aetherinox/ntfy-desktop/releases\n\n\u003c!-- BADGE \u003e NPMJS \u003e DOWNLOAD COUNT --\u003e\n  [npmjs-downloads-img]: https://img.shields.io/npm/dw/%40aetherinox%2Fntfy-desktop?logo=npm\u0026\u0026label=Downloads\u0026color=376892\n  [npmjs-downloads-uri]: https://npmjs.com/package/ntfy-desktop\n\n\u003c!-- BADGE \u003e GITHUB \u003e DOWNLOAD SIZE --\u003e\n  [github-size-img]: https://img.shields.io/github/repo-size/aetherinox/ntfy-desktop?logo=github\u0026label=Size\u0026color=59702a\n  [github-size-uri]: https://github.com/aetherinox/ntfy-desktop/releases\n\n\u003c!-- BADGE \u003e NPMJS \u003e DOWNLOAD SIZE --\u003e\n  [npmjs-size-img]: https://img.shields.io/npm/unpacked-size/ntfy-desktop/latest?logo=npm\u0026label=Size\u0026color=59702a\n  [npmjs-size-uri]: https://npmjs.com/package/ntfy-desktop\n\n\u003c!-- BADGE \u003e CODECOV \u003e COVERAGE --\u003e\n  [codecov-coverage-img]: https://img.shields.io/codecov/c/github/aetherinox/ntfy-desktop?token=MPAVASGIOG\u0026logo=codecov\u0026logoColor=FFFFFF\u0026label=Coverage\u0026color=354b9e\n  [codecov-coverage-uri]: https://codecov.io/github/aetherinox/ntfy-desktop\n\n\u003c!-- BADGE \u003e ALL CONTRIBUTORS --\u003e\n  [contribs-all-img]: https://img.shields.io/github/all-contributors/aetherinox/ntfy-desktop?logo=contributorcovenant\u0026color=de1f6f\u0026label=contributors\n  [contribs-all-uri]: https://github.com/all-contributors/all-contributors\n\n\u003c!-- BADGE \u003e GITHUB \u003e BUILD \u003e NPM --\u003e\n  [github-build-img]: https://img.shields.io/github/actions/workflow/status/aetherinox/ntfy-desktop/npm-build.yml?logo=github\u0026logoColor=FFFFFF\u0026label=Build\u0026color=%23278b30\n  [github-build-uri]: https://github.com/aetherinox/ntfy-desktop/actions/workflows/npm-build.yml\n\n\u003c!-- BADGE \u003e GITHUB \u003e BUILD \u003e Pypi --\u003e\n  [github-build-pypi-img]: https://img.shields.io/github/actions/workflow/status/aetherinox/ntfy-desktop/app-pypi.yml?logo=github\u0026logoColor=FFFFFF\u0026label=Build\u0026color=%23278b30\n  [github-build-pypi-uri]: https://github.com/aetherinox/ntfy-desktop/actions/workflows/app-pypi.yml\n\n\u003c!-- BADGE \u003e GITHUB \u003e TESTS --\u003e\n  [github-tests-img]: https://img.shields.io/github/actions/workflow/status/aetherinox/ntfy-desktop/npm-tests.yml?logo=github\u0026label=Tests\u0026color=2c6488\n  [github-tests-uri]: https://github.com/aetherinox/ntfy-desktop/actions/workflows/npm-tests.yml?logo=github\u0026label=Tests\u0026color=2c6488\n  [github-tests-uri]: https://github.com/aetherinox/ntfy-desktop/actions/workflows/app-tests.yml.yml\n\n\u003c!-- BADGE \u003e GITHUB \u003e COMMIT --\u003e\n  [github-commit-img]: https://img.shields.io/github/last-commit/aetherinox/ntfy-desktop?logo=conventionalcommits\u0026logoColor=FFFFFF\u0026label=Last%20Commit\u0026color=313131\n  [github-commit-uri]: https://github.com/aetherinox/ntfy-desktop/commits/main/\n\n\u003c!-- prettier-ignore-end --\u003e\n\u003c!-- markdownlint-restore --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAetherinox%2Fntfy-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FAetherinox%2Fntfy-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FAetherinox%2Fntfy-desktop/lists"}