Omahub
← All plugins
T

IP Scan

by tuxmontero

Local IPv4 ICMP discovery and optional TCP port scan from the Omarchy bar.

Install
$ omarchy plugin add https://github.com/tuxmontero/omarchy-ipscan --enable
Other #power-management

Omarchy IP Scan

A lightweight local network scanner for Omarchy, inspired by Angry IP Scanner.

The plugin discovers devices on the local network from the Omarchy bar. It uses QML / Quickshell for the UI, ping for ICMP host discovery, and OpenBSD nc for optional TCP connect checks.

There is no Nmap dependency, no backend daemon, and no sudo.

[!NOTE] This project is in early development. Hostname resolution is not implemented yet.

Features

  • Fast IPv4 host discovery with ping
  • Local subnet auto-detection
  • Custom IP ranges
  • Ping / latency information
  • Optional TCP port scanning with OpenBSD nc (off by default)
  • Display filters that never trigger another scan
  • Asynchronous scanning with a limited process pool
  • Scan cancellation
  • Native Omarchy look and feel
  • Integration with the Omarchy bar
  • No root privileges required

UI

The bar widget shows the scanner icon and the number of alive hosts from the last scan:

󰩟 12

Click the widget to open the panel. Middle-click starts or stops a scan. Right-click redetects the local subnet.

┌───────────────────────────────────────────────────────┐
│ IP Scanner                              Pinging 12/254│
├───────────────────────────────────────────────────────┤
│ From:      [ 192.168.1.1   ]                         │
│ To:        [ 192.168.1.254 ]                         │
│ Port Scan: [ off ]                                   │
│ Ports:     [ 22,80,443     ]          [ Start ]      │
│ Show:      [ Alive hosts           ]                 │
├────────────────┬─────────┬───────────────┬────────────┤
│ IP             │ Ping    │ Hostname      │ Ports      │
├────────────────┼─────────┼───────────────┼────────────┤
│ 192.168.1.1    │ 1.2 ms  │ —             │ —          │
│ 192.168.1.20   │ 3.4 ms  │ —             │ —          │
│ 192.168.1.50   │ 0.8 ms  │ —             │ —          │
└────────────────┴─────────┴───────────────┴────────────┘

The Ports field is enabled only when Port Scan is on. Default ports are 22,80,443.

Display filters:

  • Alive hosts (default)
  • All scanned hosts
  • Hosts with open ports

Filters only hide existing rows. They never start another scan.

Architecture

Omarchy / Quickshell
        │
        ▼
┌──────────────────────┐
│      Panel.qml       │
│   bar + panel UI     │
└──────────┬───────────┘
           │
           ├──────────────► ScanController.qml
           │                process pool
           │                scan state
           │                cancellation
           │
           ├──────────────► ProbeWorker.qml
           │                one ping/nc Process
           │
           ├──────────────► Scanner.js
           │                validation
           │                parsing
           │                IP utilities
           │
           ▼
     Quickshell Process pool (~32)
           │
           ├──────── ping
           └──────── nc

No Python, Go, or custom daemon.

manifest.json

Omarchy plugin metadata and bar-widget entry point.

Panel.qml

Bar widget and scanner panel.

  • Icon and alive-host count
  • From / To IPv4 inputs
  • Port Scan toggle (off by default)
  • Ports input (enabled only when Port Scan is on)
  • Display filter
  • Start / Stop
  • Results table: IP, Ping, Hostname, Ports

ScanController.qml

Scan engine.

  • Process queue and worker pool
  • Ping and optional TCP phases
  • Cancellation
  • Progress
  • Host result updates

ProbeWorker.qml

One reusable Quickshell Process slot. The controller assigns validated ping or nc argument arrays. User input is never passed through bash -c.

Scanner.js

Pure helpers:

  • IPv4 validation and conversion
  • Range validation and expansion
  • Port parsing
  • Ping latency parsing
  • Host result normalization
  • Display filters
  • ping / nc command builders

Scanner Workflow

Phase 1 — ICMP discovery (always)

ping -4 -n -c 1 -W 1 <ip>

Exit code 0 means the host replied. Stdout is parsed only for latency (time=).

Phase 2 — Optional TCP ports

Port scanning is off by default. When enabled, TCP probes run against every address in the range, including hosts that did not reply to ping. There is no UDP scanning.

Default ports: 22, 80, 443.

nc -4 -z -n -w 1 <ip> <port>

Exit code 0 means the port is open. Closed vs filtered is not classified.

A host is alive if ICMP replied or at least one selected TCP port is open.

The plugin does not require sudo.

Scanner States

Port Scan OFF:
  IDLE -> PING_SCANNING -> FINISHED

Port Scan ON:
  IDLE -> PING_SCANNING -> PORT_SCANNING -> FINISHED

A scan can also transition to:

CANCELLING
CANCELLED
ERROR

Both phases can be cancelled. The UI never blocks while probes are running.

Current Status

  • Omarchy plugin manifest
  • Bar widget
  • Scanner panel
  • Start / stop / cancel
  • IPv4 and range validation
  • Local subnet detection
  • ICMP discovery via ping
  • Latency
  • Optional TCP ports via nc
  • Display filters
  • Sort hosts by IP
  • Alive-host counter
  • Scan status and progress
  • Error handling
  • Omarchy-compatible styling
  • Hostname resolution
  • omarchy plugin validate on the Omarchy test machine

Future Ideas

  • Hostname / mDNS / Avahi enrichment
  • MAC and vendor detection
  • Custom port profiles
  • Sort by IP / hostname / latency
  • Copy IP or hostname
  • SSH / HTTP / HTTPS actions
  • Wake-on-LAN
  • Favorite hosts
  • Scan history and CSV / JSON export
  • Multiple network interfaces
  • IPv6

Development Environment

Developed on Linux Mint and tested on Omarchy.

Linux Mint
├── Git
├── ping
├── OpenBSD netcat
├── QML tooling
└── omarchy-ipscan/

Omarchy itself is only required for integration testing.

Linux Mint
   │
   │ develop
   ▼
omarchy-ipscan
   │
   │ git / rsync
   ▼
Omarchy machine or VM
   │
   ▼
omarchy-shell

Local checks:

node tests/scanner-test.js
qmlformat -i Panel.qml ScanController.qml ProbeWorker.qml

A missing Omarchy runtime on Linux Mint is not a build failure.

Testing on Omarchy

rsync -av --delete \
    ~/Code/omarchy-ipscan/ \
    omarchy:~/.config/omarchy/plugins/io.github.tuxmontero.ipscan/

Then reload the shell plugin and test in omarchy-shell.

These commands must only be run on the Omarchy test machine:

omarchy plugin validate
omarchy plugin enable
omarchy plugin rescan

Development Principles

Do not block the UI

Network operations run asynchronously through a limited Quickshell process pool.

Do not use sudo

The plugin works with normal user permissions and TCP connect checks.

Do not use bash -c

Commands use explicit argument arrays after validation:

command: ["ping", "-4", "-n", "-c", "1", "-W", "1", ip]
command: ["nc", "-4", "-z", "-n", "-w", "1", ip, port]

Validate every target

User-controlled IP addresses, ranges, and ports are validated before any process starts.

Keep parsing outside the UI

Panel.qml owns UI only. ScanController.qml owns scan state and the process pool. Scanner.js owns parsing and IP utilities.

Do not invent Omarchy APIs

Inspect current Omarchy source and official plugins before adding integration behavior.

Dependencies

Runtime:

Omarchy
Quickshell
ping
OpenBSD netcat
iproute2

Development:

Git
Node.js (for Scanner.js tests)
qmllint
qmlformat

Security

This plugin executes network scanning commands from inside the Omarchy shell.

  • Inputs must always be validated
  • Shell interpolation is avoided
  • Root privileges are not required
  • Scan sizes are limited
  • External commands never execute arbitrary user input

Only scan networks and systems you own or are authorized to test.

Contributing

The project is in early development. Issues, ideas, and pull requests are welcome.

License

Omarchy IP Scan is released under the MIT License.