Skip to content

About

Rust Tauri lightweight toast notification for Windows, Linux

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Nonstop Notify banner

Build MIT License Rust Platforms

Nonstop Notify

Nonstop Notify is a lightweight desktop notification bridge for scripts, automation, CI jobs, background services, and local developer tools. Send one JSON event through the CLI and it turns into a focused desktop toast.

It was originally built for the Nonstop test platform, but the event format and CLI are suitable for any workflow that needs visible desktop feedback.

Contents

Highlights

  • Accepts notifications as JSON through standard input or a command argument.
  • Starts a single background daemon automatically on the first event.
  • Updates an existing toast when the same toastId is reused.
  • Supports loading, success, error, warning, and informational states.
  • Shows optional progress, messages, and primary or secondary actions.
  • Keeps loading notifications visible until they are updated or dismissed.
  • Displays up to five notifications with compact hover expansion.
  • Follows the Windows light or dark app theme and uses the light theme on other platforms.
  • Supports configurable screen position, offsets, and border width.
  • Supports explicit custom sounds and a runtime notify-ring.mp3 override beside the executable.
  • Opens safe relative dashboard routes or absolute HTTP(S) URLs.

Quick Start

Windows

No configuration is required for a first notification. Verify the executable, then send an event:

.\nonstop-notify.exe --self-check

Send an event from PowerShell:

'{"event":"deploy.started","toastId":"deploy:api","title":"Deploying API","message":"Publishing to staging","status":"loading","progress":0.35}' |
  .\nonstop-notify.exe emit --stdin

Update the same toast when the work finishes:

'{"event":"deploy.completed","toastId":"deploy:api","title":"Deployment complete","message":"Staging is ready","status":"success","progress":1,"primaryLabel":"View deployment","primaryRoute":"https://example.com/deployments/42"}' |
  .\nonstop-notify.exe emit --stdin

The daemon starts automatically. Running it explicitly is optional:

.\nonstop-notify.exe daemon

Linux

After installing the DEB package or placing the AppImage binary on PATH, verify it, then send an event from Bash:

nonstop-notify --self-check
printf '%s\n' '{"event":"deploy.started","toastId":"deploy:api","title":"Deploying API","message":"Publishing to staging","status":"loading","progress":0.35}' |
  nonstop-notify emit --stdin

Update the same toast:

printf '%s\n' '{"event":"deploy.completed","toastId":"deploy:api","title":"Deployment complete","message":"Staging is ready","status":"success","progress":1,"primaryLabel":"View deployment","primaryRoute":"https://example.com/deployments/42"}' |
  nonstop-notify emit --stdin

The daemon also starts automatically on Linux. Running it explicitly is optional:

nonstop-notify daemon

CLI

nonstop-notify emit --stdin [--config PATH]
nonstop-notify emit --json JSON [--config PATH]
nonstop-notify daemon [--config PATH]
nonstop-notify --self-check [--config PATH]
nonstop-notify config show [--config PATH]
nonstop-notify config set <key> <value> [--config PATH]
nonstop-notify status
nonstop-notify log
nonstop-notify start [--config PATH]
nonstop-notify stop
Command Purpose
emit --stdin Reads one JSON event from standard input.
emit --json Reads one JSON event from the next command argument.
daemon Starts the background notification process.
--self-check Validates configuration, event parsing, sound decoding, and URL handling.
config show Prints effective JSON config and selected config path. Does not create a file.
config set Validates and atomically writes one config value; restarts a healthy daemon.
status Prints running, stopped, or stale-heartbeat unresponsive JSON.
log Prints raw JSONL content from the newest log file.
start Starts a healthy daemon or returns its existing PID.
stop Sends graceful stop control; already-stopped daemon is success.

Set NONSTOP_NOTIFY_DEBUG=1 to print CLI errors. Set NONSTOP_NOTIFY_CONFIG to provide a default configuration file without passing --config each time.

Event Format

Minimal event:

{
  "event": "job.completed",
  "title": "Job completed",
  "status": "success"
}

Full example:

{
  "schemaVersion": 1,
  "event": "backup.progress",
  "toastId": "backup:nightly",
  "groupId": "maintenance",
  "timestamp": "2026-07-26T12:00:00Z",
  "title": "Nightly backup",
  "message": "Uploading archive 7 of 10",
  "status": "loading",
  "progress": 0.7,
  "route": "https://example.com/backups/nightly",
  "actions": [
    {
      "label": "Open logs",
      "route": "https://example.com/backups/nightly/logs",
      "kind": "primary"
    }
  ]
}
Field Description
event Required event name. Also used as the title when title is empty.
toastId Stable identifier used to update an existing toast. Generated when omitted.
title Notification heading.
message Optional supporting text.
status loading, success, error, warning, or another informational value. state is accepted as an alias.
progress Optional number clamped to the 0 to 1 range.
route Fallback URL for the primary Open action when no explicit action route is supplied.
actions Optional action buttons with label, route, and kind.
primaryLabel / primaryRoute Flat-field alternative for a primary action.
secondaryLabel / secondaryRoute Flat-field alternative for a secondary action.

Relative routes beginning with / open against the default local Nonstop dashboard at http://127.0.0.1:4137. General integrations should use absolute http:// or https:// URLs. Empty, protocol-relative, javascript:, and file: routes are rejected.

Configuration

Configuration precedence is --config PATH, NONSTOP_NOTIFY_CONFIG, the per-user config file, then built-in defaults. config show reports effective values and does not create the default file.

Default config paths:

  • Windows: %LOCALAPPDATA%\Nonstop Notify\config.json
  • Linux: $XDG_CONFIG_HOME/nonstop-notify/config.json, falling back to ~/.config/nonstop-notify/config.json

Those paths are only fallbacks. A config file can live anywhere: pass its path with --config PATH, or set NONSTOP_NOTIFY_CONFIG to that path. --config wins over the environment variable and per-user default.

.\nonstop-notify.exe config set position bottom-right --config D:\tools\nonstop-notify\config.json
.\nonstop-notify.exe emit --stdin --config D:\tools\nonstop-notify\config.json

Default config sample. Copy this structure into config.json when creating a per-user config:

{
  "position": "bottom-left",
  "offsetLeft": 30,
  "offsetRight": 30,
  "borderWidth": 1,
  "soundPath": null,
  "logRotationHours": 24,
  "logRetentionDays": 7
}

Supported positions: top-left, top-right, bottom-left, and bottom-right.

config set supports position, offsetLeft, offsetRight, borderWidth, soundPath, logRotationHours, and logRetentionDays. Use soundPath none to write null.

soundPath is optional and takes precedence when set. When omitted or null, the daemon first checks for a decodable notify-ring.mp3 beside the executable. If that runtime override is missing or invalid, Windows uses the native system notification sound and other platforms play a short deterministic WAV generated during the Rust build.

--self-check fails when an explicit soundPath cannot be read or decoded. A missing or invalid adjacent notify-ring.mp3 falls back to the default sound without discarding notifications; set NONSTOP_NOTIFY_DEBUG=1 to log the fallback.

Management examples:

.\nonstop-notify.exe config show
.\nonstop-notify.exe config set position bottom-right
.\nonstop-notify.exe config set soundPath none
.\nonstop-notify.exe start
.\nonstop-notify.exe status
.\nonstop-notify.exe log
.\nonstop-notify.exe stop

config set validates values and atomically writes config.json. A healthy running daemon receives graceful stop, then starts with new config; a stopped daemon only saves the file. An unresponsive daemon is not force-killed. If restart fails after saving, the command exits 1 and returns configSaved: true on stderr.

Management errors are JSON on stderr with exit code 1. emit stays silent unless NONSTOP_NOTIFY_DEBUG is set.

Runtime state is stored in runtime.json beside the config. JSONL logs are stored in logs/current.log; files rotate after logRotationHours (default 24) and files whose modified time is at least logRetentionDays old (default 7 days) are removed. Logs contain lifecycle and event metadata only; notification title, message, route, actions, and payload JSON are never written.

.\nonstop-notify.exe emit --stdin --config .\nonstop-notify.config.json

Install

Tagged GitHub releases are built for:

  • Windows x64 as a portable executable.
  • Linux x64 as DEB and AppImage packages.

Windows

Install with WinGet after the package is published:

winget install --id quangnv13.nonstop-notify --exact

WinGet installs the portable executable and registers the nonstop-notify command. This release does not mutate User PATH. Close existing terminal windows, open a new terminal, then verify the CLI:

nonstop-notify --self-check

You can also download the Windows .exe directly from a GitHub release and run it without an installer. To remove the WinGet package:

winget uninstall --id quangnv13.nonstop-notify --exact

Linux DEB

The DEB package installs nonstop-notify in /usr/bin, so the CLI is immediately available:

nonstop-notify --self-check

Linux AppImage

AppImage is portable and does not install itself or update PATH:

chmod +x ./Nonstop.Notify_0.1.2_amd64.AppImage
./Nonstop.Notify_0.1.2_amd64.AppImage --self-check

Create a stable CLI command when ~/.local/bin is on PATH:

mkdir -p ~/.local/bin
ln -s "$PWD/Nonstop.Notify_0.1.2_amd64.AppImage" ~/.local/bin/nonstop-notify
nonstop-notify --self-check

Until a release is published, build from source using the steps below.

Build from Source

Requirements:

  • Node.js 22+
  • Rust stable
  • Tauri v2 system dependencies for the target operating system
npm.cmd ci --prefix ui-react --ignore-scripts
npm.cmd --prefix ui-react run build
cargo test --locked
cargo tauri build --no-bundle # Windows portable executable
cargo tauri build --bundles deb,appimage # Linux packages

For frontend development:

npm.cmd --prefix ui-react run dev

Privacy and Security

  • Notification events remain on the local machine.
  • The app does not include analytics, telemetry, advertising, or user accounts.
  • Event queue and daemon lock files are stored in the operating system temporary directory; config, runtime state, and logs stay in the per-user data directory described above.
  • Notification actions open only relative dashboard routes or absolute HTTP(S) URLs.
  • Treat notification text as visible desktop content and avoid sending secrets in events.

Code Signing Policy

Free code signing provided by SignPath.io, certificate by SignPath Foundation.

  • Source repository: quangnv13/nonstop-notify
  • Build system: GitHub-hosted GitHub Actions runners
  • Committers and reviewers: quangnv13
  • Approvers: quangnv13
  • Signing is limited to release artifacts produced from version tags by the repository workflow.
  • Signing credentials are not stored in the repository or exposed to project maintainers.
  • Privacy policy: This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it.

Current eligibility and application work are tracked in docs/signpath-free-code-signing-checklist.md.

Release

Release and WinGet submission steps are documented in RELEASING.md.

License

Licensed under the MIT License.

About

Rust Tauri lightweight toast notification for Windows, Linux

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages