webShark v3.0.0 brings PCAP dissection into your browser (Wireshark 4.4.5 WASM)
- Baseline Wireshark UI/UX
- No sharkd or backend needed
- 100% WASM packet dissection
- Load/Save PCAP/PCAPNG/CAP
| Layer | Role |
|---|---|
| Browser | Wiregasm worker loads the capture into WASM memory and answers frames, details, filters, I/O graph, Follow Stream, VoIP Calls, RTP Streams/Analyze/Player, conversations, endpoints, export objects. |
Fastify (:8085) |
Serves the UI, lists/uploads/downloads files under CAPTURES_PATH, live-follows growing files over SSE. It does not run sharkd or dissect packets. |
| Static / GitHub Pages | Same UI with clientOnly: true. No API. Users open PCAPs from disk; nothing is uploaded. |
Mount a capture directory at /captures and start the API + UI:
docker-compose up -d
# or
docker run -ti --rm -p 8085:8085 -v $(pwd)/captures:/captures ghcr.io/qxip/webshark:latestOpen http://localhost:8085/webshark.
npm --prefix ui ci
npm --prefix api ci
export CAPTURES_PATH=$(pwd)/captures/
npm run build:ui
npm --prefix api run devhttp://localhost:8085/webshark/?capture=voip.pcapng&frame=12&filter=sip&view=rtp
Query keys: capture, frame, filter, view (rtp | voip | flow | follow | iograph | expert), stream (RTP 5-tuple token), follow, embed=1.
File menu: Open a local capture, close, export displayed/filtered packets as classic PCAP, download the original file, export HTTP/TFTP/SMB objects. Click WebShark in the header to return to the open-capture screen.
Growing files (tcpdump -w / dumpcap writing into /captures) are followed over GET /webshark/watch (SSE). The packet list appends; dissection still happens in WASM.
No server and no capture storage. Drop a PCAP in the page; Wiregasm dissects it locally.
npm --prefix ui run build:static
# output: ui/dist/webshark
npm --prefix ui start -- --configuration static # local previewPushing to main/master publishes that build to GitHub Pages (.github/workflows/github-pages.yml). Enable Settings → Pages → Source: GitHub Actions once. The base href is /<repo>/ (or / for user.github.io repos).
RTP playback uses FFmpeg.wasm and needs a cross-origin isolated HTTPS origin (GitHub Pages + enable-threads.js). Local HTTP will not play audio.
Kiosk build (WEBSHARK_UI_MODE=kiosk) hides the file browser. Embed with embed=1 or /webshark/embed/<view>:
<iframe
src="http://localhost:8085/webshark/?capture=voip.pcapng&view=rtp&embed=1"
style="width:100%;height:100%;border:0"
allow="fullscreen"
></iframe>Hosts that iframe webshark should set Content-Security-Policy: frame-ancestors on their own origin.
The UI talks to Wiregasm in-process. The API is file I/O:
| Method | Purpose |
|---|---|
GET /webshark/json?method=files |
List captures |
GET /webshark/captures/:name |
Raw PCAP bytes for the worker |
POST /webshark/upload |
Store an upload under CAPTURES_PATH |
GET /webshark/watch?capture=… |
SSE capture-changed {size,mtime,kind} (init | append | full) |
Dissection methods (frames, frame, tap, follow, …) are rejected. Uploads stream to disk (UPLOAD_MAX_BYTES, default 2 GiB).
Set STENOGRAPHER_URL to pull a remote PCAP into CAPTURES_PATH:
curl -X POST http://localhost:8085/webshark/stenographer \
-H 'content-type: application/json' \
-d '{"query":"port 5060 and after 1m ago","name":"sip-last-minute.pcap"}'Status: GET /webshark/stenographer/status
npm test
# or
npm --prefix api test
npm --prefix ui test| Arg | Default | Purpose |
|---|---|---|
WEBSHARK_UI_MODE |
full |
full shows the capture list; kiosk hides it |
docker build --build-arg WEBSHARK_UI_MODE=full -t webshark .The image builds the Angular UI (and Wiregasm WASM assets) in a Node stage. It does not compile sharkd.
GPLv2 fork of webshark by Jakub Zawadzki, sponsored by qxip.
Dissection in the browser is Wiregasm / Wireshark. See LICENSE.