Today I'm open-sourcing NetEngine — a private, local-first desktop command center for real network work. It puts a scanner, an embedded terminal, multi-tab SSH, SFTP file transfer, adapter control, a live link monitor, an API console, and an AI automation layer into one keyboard-driven app. No accounts. No cloud. No subscription. Just download it, or run it from source in about a minute.
This post is the build story: the problem that pushed me to make it, the architecture that holds eight tools together without turning into spaghetti, the hard parts, what I learned, and why I decided to give the whole thing away.
The Problem: Death by Context-Switching
If you've ever done hands-on network work — setting up a homelab, debugging a flaky connection, provisioning a fleet of machines, or just figuring out what is actually on this subnet — you know the ritual. It goes something like this:
- Open a scanner (or
nmapin a terminal) to find live hosts. - Copy an IP into PuTTY to SSH in.
- Open WinSCP or FileZilla in a separate window to move files to that same host.
- Keep a ping window running to watch if the link drops.
- Fire up Postman to hit an internal API on that box.
- Drop into PowerShell for the commands the GUI tools can't do.
- Dig through adapter settings buried five clicks deep in the OS to switch a static IP.
That's seven tools, each with its own window, its own connection state, its own copy-paste dance. The actual work — the thinking — gets drowned in tool management. You lose your place constantly. The IP you scanned isn't the IP your SSH client knows about. The file you want to transfer is in a session the transfer tool can't see.
The insight behind NetEngine is simple: all of these tools operate on the same context — the same hosts, the same sessions, the same network. So why are they seven separate programs that know nothing about each other? What if the scanner result flowed straight into an SSH session, and that SSH session was already wired to the file-transfer pane, and the AI assistant could see all of it?
That "what if" became NetEngine.
What NetEngine Actually Is
NetEngine is a cross-platform desktop application built in Python with PyQt6. It ships as a native build for Windows (.exe), macOS (.dmg), and Linux (.AppImage / .deb), or you can run it from source with Python 3.10+. Everything runs on your machine — it's local-first by design, with no telemetry and no account wall.
Behind one keyboard-driven sidebar are eight tools:
| # | Tool | What it does |
|---|---|---|
| 01 | Network Scanner | Live subnet sweep — finds hosts, vendors, latency, reachability, and open ports in one focused table. |
| 02 | Embedded Terminal | PowerShell, CMD, WSL, or bash in the same workspace, with history and shortcuts. |
| 03 | SSH Sessions | Multi-tab SSH with saved profiles, persistent scrollback, and one-click reconnect. |
| 04 | File Transfer | Dual-pane SFTP browser with a live transfer queue, wired directly to your SSH sessions. |
| 05 | Adapter Control | Inspect interfaces and switch DHCP ↔ static with named, saved profiles. |
| 06 | Live Monitor | Continuous ping, packet loss, and latency you can read at a glance. |
| 07 | API Console | Probe endpoints with methods, auth, headers, JSON bodies, and saved requests. |
| 08 | AI Assistant | Automate approved tasks and explain results using Ollama, OpenAI, or Groq. |
The tagline I landed on says it best: eight tools, zero context switching. Everything a network job needs, behind one sidebar.
The Architecture: How Eight Tools Share One Brain
The hardest engineering problem in NetEngine isn't any single tool — a port scanner or an SFTP browser are well-trodden ground. The hard part is making eight tools coexist in one process without stepping on each other, while sharing enough state to feel like a single application.
Here's the shape of the solution.
A responsive UI over blocking work
Network work is slow and blocking by nature. A subnet sweep pings 254 hosts. An SSH handshake waits on a remote server. A file transfer streams megabytes. If any of that runs on the UI thread, PyQt6 freezes — the spinner of death.
The rule I held to everywhere: the GUI thread only paints; work happens off it. Each long-running operation — a scan, an SSH channel, a transfer job — runs on a Qt worker thread (QThread / QThreadPool) and communicates back to the UI exclusively through signals and slots. The scanner emits a hostFound signal per discovered host, and the results table appends a row. The transfer worker emits progress per chunk, and the queue's progress bar advances. Nothing blocks; the app stays buttery even during a full sweep.
The single most important lesson from building a desktop app that does real I/O: your event loop is sacred. Every blocking call you accidentally leave on it is a freeze your users will feel. Signals and slots aren't boilerplate — they're the whole discipline.
Shared session state as the backbone
The reason the tools feel connected is a shared session/context layer that sits underneath all eight panels. When the scanner finds a host, that host is a first-class object other tools can act on. When you open an SSH session, the file-transfer pane can attach to that same connection rather than reconnecting. The AI assistant reads from this shared context so it can reason about "the scan you just ran" or "the session you're in."
This is the architectural payoff of putting everything in one app: state stops being trapped inside separate programs. A scanned IP, an open SSH channel, and an SFTP browser are all views onto the same underlying connection.
A plugin-shaped tool model
Adding an eighth tool shouldn't require rewiring the other seven. Each tool is a self-contained panel that registers with the sidebar and talks to the rest of the app through the shared context and a common signal bus. That boundary is what kept the codebase from collapsing under its own weight as it grew from a scanner into a full console.
The AI Layer: Automation That Asks Permission First
The part I'm most proud of is the AI automation layer — and specifically the way it's designed to be trustworthy, not just impressive.
The assistant can take plain English — "check which hosts on this subnet have SSH open and aren't responding to ping" — and turn it into a concrete plan. But here's the key design decision: plain English becomes a reviewed action plan before anything runs. The AI never silently executes commands against your network. It proposes; you approve. AI-suggested terminal commands are inserted, not auto-run. Automation is scoped to approved tasks.
The other deliberate choice was provider independence:
- Ollama runs models fully locally on
localhost:11434— the whole app, AI included, works with zero internet and zero data leaving your machine. - OpenAI and Groq plug in via API key when you want hosted horsepower — "borrowing someone else's GPUs," as I put it on the site.
That local-first default matters. Network diagnostics touch sensitive infrastructure. Sending your internal topology to a cloud model by default would be the wrong trade. With Ollama, the private path is the default path, and the cloud is opt-in.
The Hard Parts (and What They Taught Me)
Every project's real lessons live in the parts that fought back. A few that stuck with me:
Threading discipline is non-negotiable. My earliest builds froze constantly because I'd sneak a blocking call onto the UI thread "just this once." The fix wasn't cleverness — it was rigor. Every I/O path gets a worker; every result comes back over a signal. Once I internalized that, whole categories of bugs disappeared.
Cross-platform is a tax you pay continuously, not once. PowerShell vs. CMD vs. WSL vs. bash. Windows adapter APIs vs. Linux ip/nmcli vs. macOS networksetup. Path separators, permission models, the way each OS reports network interfaces — they're all different. Abstracting the terminal backend and the adapter control behind a common interface, so the UI didn't care which platform it ran on, was some of the most finicky and valuable work in the project.
"Local-first" is an architecture, not a label. It's easy to say "no cloud." It's harder to mean it — to make sure the scanner, the AI, the profiles, and the saved requests all persist and function with the network unplugged. Designing for offline from day one forced cleaner boundaries everywhere.
Packaging a Python GUI is its own boss fight. Turning a PyQt6 app into a 44 MB double-clickable .exe (and a .dmg, and an .AppImage) meant wrestling with bundlers, hidden imports, and native dependencies. It's the unglamorous 20% that decides whether normal people can actually use what you built — so it's worth doing well.
Good defaults beat more features. The seven themes — Dark, Neon, Space, Liquid Glass, Light, OG Black, Retro Terminal — and the always-visible status bar (activity, current tool, live CPU/memory, clock) weren't afterthoughts. Deep work loses its place easily; the details that keep you oriented are what make a tool something you reach for instead of just have installed.
The Tech Stack, End to End
For anyone who wants to build something similar, here's the stack that made NetEngine work:
| Layer | Choice | Why |
|---|---|---|
| Language | Python 3.10+ | Fast to build, huge networking ecosystem, cross-platform. |
| GUI framework | PyQt6 | Native performance, mature widget set, real threading via QThread. |
| Concurrency | Qt signals/slots + worker threads | Keeps the UI responsive over blocking network I/O. |
| SSH / SFTP | Paramiko-style SSH transport | Multi-session SSH and a dual-pane transfer queue on one connection layer. |
| Local AI | Ollama (localhost:11434) | Fully offline model inference, private by default. |
| Cloud AI | OpenAI + Groq | Optional hosted models via API key. |
| Packaging | Native bundlers per-OS | Ships .exe, .dmg, .AppImage/.deb. |
| Landing site | Next.js | The netengine.sharvik.tech marketing/download page. |
Why I'm Making It Open Source
I built NetEngine to solve my own problem. But the more I used it, the more it felt like the kind of tool that shouldn't be locked up.
Network tooling is fragmented, and a lot of the good stuff is either paid, cloud-tethered, or telemetry-heavy. A private, local-first console that respects your machine and your data is something I'd want to exist whether or not I'd built it — so making it free and open source was the natural move. It means anyone can audit exactly what it does with their network (which, for a tool that touches your infrastructure, matters), extend it with tools I haven't thought of, and never worry about a login wall or a subscription showing up later.
It's on GitHub at github.com/SharvikS/NetEngine. Issues, pull requests, and new-tool ideas are all welcome.
Try It
You can grab NetEngine right now:
- Download the native build for Windows, macOS, or Linux.
- Run from source in about a minute:
# any platform, Python 3.10+
git clone https://github.com/SharvikS/NetEngine.git
cd NetEngine && pip install -r requirements.txt
python main.py
- For AI features, install Ollama for the fully-local path, or drop in an OpenAI/Groq key.
Stop switching tools. Start closing tickets. NetEngine gives you the scanner, the shell, the transfer queue, the monitor, the API console, and the AI automation layer in one private desktop console — and now, all of the source too.