NexMap is an advanced parser and formatter for Nmap and RustScan outputs, transforming raw scan data into beautifully formatted terminal reports and professional multi-format exports. Built for security professionals who need more than plain text.
NexMap is a transformation layer, not a wrapper. It doesn't execute scansβit makes existing scan outputs infinitely better.
- Overview
- Features
- Installation
- Quick Start
- Usage Examples
- Command Reference
- Design Philosophy
- Architecture
- Export Formats
- Tips & Best Practices
- Development
- Troubleshooting
- License & Credits
NexMap sits between your scanning tools (Nmap, RustScan) and your analysis workflow, providing:
- Beautiful Terminal UI: Multi-colored ASCII banner, rich tables, progress bars, and structured panels powered by Rich
- Intelligent Parsing: Auto-detects and parses Nmap XML, Nmap stdout, and RustScan outputs
- Interactive Mode: Seamlessly integrates with RustScan for high-speed discovery + targeted deep scanning (auto-enabled!)
- Professional Exports: Generate reports in JSON, CSV, HTML, XML, and TXT formats simultaneously
- Safety First: Prerequisite checking, privilege detection, input validation, and comprehensive error handling
Unlike traditional Nmap wrappers that try to execute scans, NexMap focuses exclusively on what matters: parsing, formatting, and presenting scan data. This focused approach means:
β
Works with your existing Nmap/RustScan workflows
β
No need to learn new scanning syntax
β
Cleaner, more maintainable codebase
β
Better compatibility and fewer edge cases
- Multi-colored ASCII banner with boxed design for professional presentation
- Real-time progress indicators with spinners and progress bars for all scan modes
- Color-coded tables showing hosts, ports, services, and vulnerabilities
- Structured panels for OS detection, hostnames, and detailed service information
- Smart TTY detection for clean piped output (banner auto-hides when output is redirected)
- Interactive RustScan Integration: Pipe RustScan output directly β NexMap orchestrates targeted Nmap scans β formatted results
- Auto-detection: Interactive mode automatically enabled when piping with Nmap arguments (no flag needed!)
- Multi-format exports: JSON, CSV, HTML, XML, TXT (one command, multiple outputs)
- Flexible parsing: Handle Nmap XML, Nmap stdout, RustScan formats automatically
- Concurrent scanning: Configurable worker threads for faster interactive mode processing
- File batch processing: Process existing scan results from saved files
- Prerequisite checking: Automatically detects Nmap installation with OS-specific install instructions
- Privilege detection: Warns when scans require sudo/root privileges
- Input validation: Validates Nmap flags before execution
- Comprehensive error handling: Rich UI error messages instead of cryptic stack traces
- Safe defaults: Sensible fallbacks and clear user guidance
Before installing NexMap, ensure you have:
- Python 3.8+ (Download Python)
- Nmap 7.90+ (Download Nmap) - Required for interactive mode
- RustScan (Install RustScan) - Optional, but highly recommended for fast discovery
Install NexMap globally and run it from anywhere:
# Clone the repository
git clone https://github.com/Real-Fruit-Snacks/nexmap.git
cd nexmap
# Install with pipx
pipx install .Why pipx? It installs NexMap in an isolated environment while making the nexmap command globally available.
# Clone the repository
git clone https://github.com/Real-Fruit-Snacks/nexmap.git
cd nexmap
# Install dependencies
pip install -r requirements.txt
# Or install as a package
pip install .NexMap requires the following Python packages:
rich>=13.0.0- Beautiful terminal formattingpydantic>=2.0.0- Data validation and modelslxml>=4.9.0- XML parsingpyyaml>=6.0.0- YAML support for exports
These are automatically installed during setup.
The recommended way to use NexMap is by piping RustScan outputβinteractive mode is automatically enabled when you provide Nmap arguments:
# Basic interactive scan (auto-detected, no --interactive flag needed!)
rustscan -a 192.168.1.0/24 --ulimit 5000 | nexmap -sV
# Full scan with exports
rustscan -a targets.txt --ulimit 5000 | nexmap -A --threads 10 --export-format json html csvWhat happens:
- π RustScan performs ultra-fast port discovery
- π NexMap receives port data in real-time
- π― NexMap automatically enables interactive mode (detects Nmap args)
- π NexMap triggers targeted Nmap scans for discovered ports
- π Live progress bars show scanning status
- π¨ Results displayed with beautiful formatting
- πΎ (Optional) Exports to multiple formats
Process saved scan results:
# Parse Nmap XML file
nexmap --file scan.xml
# Parse with export
nexmap --file nmap_output.xml --export-format json csv htmlPipe Nmap output directly to NexMap for simple parsing:
# Pipe XML output (simple parsing)
nmap -sV 192.168.1.1 -oX - | nexmap
# With exports
nmap -A scanme.nmap.org -oX - | nexmap --export-format json htmlFast subnet scan with service detection:
# Interactive mode auto-enabled (has Nmap args: -sV)
rustscan -a 192.168.1.0/24 | nexmap -sV --threads 10Aggressive scan with all exports:
# Interactive mode auto-enabled (has Nmap args: -A)
rustscan -a 10.0.0.1 --ulimit 5000 | nexmap -A --export-format json csv html xml txt --export-dir /tmp/scansMultiple targets from file:
# Interactive mode auto-enabled (has Nmap args: -sV -sC)
rustscan -a targets.txt | nexmap -sV -sC --threads 15Scan with timing options:
# Interactive mode auto-enabled (has Nmap args: -T4 -sV)
rustscan -a 192.168.1.1-254 | nexmap -T4 -sV --version-intensity 5Explicit interactive mode (optional, for clarity in scripts):
# Using --interactive explicitly for self-documenting commands
rustscan -a target | nexmap --interactive -sVParse single file:
nexmap --file scan.xmlBatch convert formats:
# Convert all XML files to JSON
for file in scans/*.xml; do
nexmap --file "$file" --export-format json --export-dir ./converted/
doneParse and export to all formats:
nexmap --file comprehensive_scan.xml --export-format json csv html xml txtSimple parsing (no interactive mode):
# No Nmap args = simple XML parsing
nmap -sV 192.168.1.1 -oX - | nexmapForce simple parsing from stdin:
# Use --file - to force non-interactive parsing
nmap -sV target -oX - | nexmap --file -Export all formats at once:
# Export to all formats (JSON, CSV, HTML, XML, TXT)
nexmap --file scan.xml --export-format all
# Interactive scan with all export formats
rustscan -a 192.168.1.1 | nexmap -A --export-format all --export-dir ./reportsCustom export directory:
rustscan -a 192.168.1.1 | nexmap -sV --export-dir ~/security/reportsMultiple formats simultaneously:
nmap -sV target.com -oX - | nexmap --export-format json csv htmlExport timestamp structure:
nexmap_exports/
βββ scan_20260205_213245/
βββ scan.json
βββ scan.csv
βββ scan.html
βββ scan.xml
βββ summary.txt
High-performance scanning:
rustscan -a 10.0.0.0/16 --ulimit 10000 | nexmap -T4 -sV --threads 20Disable prerequisite checks (CI/CD environments):
rustscan -a target | nexmap -sV --no-checkVerbose debugging:
rustscan -a 192.168.1.1 | nexmap -A --verbose| Flag | Description | Default |
|---|---|---|
--file <path>, -f |
Parse existing scan file (XML or stdout). Use --file - to force simple parsing from stdin. |
None |
--verbose, -v |
Enable debug logging | False |
--no-check |
Skip prerequisite and permission checks | False |
| Flag | Description | Default |
|---|---|---|
--interactive |
Optional. Explicitly enable interactive mode (auto-detected when stdin has Nmap args) | Auto-detect |
--threads <N> |
Concurrent Nmap worker threads | 3 |
[nmap_args] |
Any valid Nmap arguments (e.g., -A, -sV, -T4). Triggers interactive mode. |
None |
Auto-Detection Rules:
- β Stdin + Nmap args β Interactive mode (no flag needed)
- β Stdin + no args β Simple parsing
- β --file path β File parsing
- β --file - β Force simple stdin parsing (non-interactive)
| Flag | Description | Default |
|---|---|---|
--export-format <formats> |
Space-separated list: json csv html xml txt all (use all for all formats) |
None |
--export-dir <path> |
Export directory (creates timestamped subdirectory) | ./nexmap_exports |
View all examples and documentation:
nexmap --helpTraditional Nmap Wrapper:
β wrapper-tool -sV 192.168.1.1
βββ Executes Nmap internally
βββ Tries to replicate all Nmap features
βββ Introduces complexity and bugs
NexMap Approach:
β
nmap -sV 192.168.1.1 -oX - | nexmap
βββ Uses Nmap directly
βββ Focuses on parsing and formatting
βββ Clean separation of concerns
π― Separation of Concerns
- RustScan/Nmap: Discovery and scanning (what they do best)
- NexMap: Parsing and presentation (what it does best)
π§ Maximum Flexibility
- Use any Nmap flags you want
- Combine with other tools
- No artificial limitations
π‘οΈ Reliability
- Fewer moving parts = fewer bugs
- No scan execution edge cases
- Focus on parsing accuracy
π Compatibility
- Works with existing workflows
- Just add a pipe
- No workflow changes needed
β Perfect For:
- Formatting RustScan + Nmap workflows (interactive mode auto-enabled!)
- Converting Nmap XML to modern formats (JSON, CSV, HTML)
- Creating professional security reports
- Real-time visualization of scan progress
- Batch processing historical scan files
- CI/CD pipeline integration
β Not Designed For:
- Standalone scanning without Nmap/RustScan
- Replacing Nmap or RustScan
- Direct host/port scanning without piping
NexMap follows a clean, modular architecture built on industry-standard design patterns:
nexmap/
βββ core/ # Core business logic
β βββ engine.py # Scan orchestration & interactive mode
β βββ export.py # Multi-format export manager
β βββ models.py # Pydantic v2 data models
β βββ utils.py # System checks & validation
β βββ logger.py # Logging configuration
βββ parsers/ # Parser suite (Factory pattern)
β βββ base.py # Abstract base parser
β βββ nmap_xml.py # Nmap XML parser
β βββ nmap_stdout.py # Nmap stdout parser
β βββ rustscan.py # RustScan parser
β βββ __init__.py # Parser factory registry
βββ interface/ # Presentation layer
βββ cli.py # CLI argument handling
βββ formatter.py # Rich UI components
Factory Pattern (parsers/__init__.py)
@ParserFactory.register
class NmapXMLParser(BaseParser):
def can_parse(self, content: str) -> bool:
# Auto-detect format
def parse(self, content: str) -> ScanResult:
# Parse to unified modelPydantic Models (core/models.py)
- Strict validation with Pydantic v2
- Type safety throughout the application
- Automatic serialization for exports
Modular Exports (core/export.py)
- Plugin-style export system
- Easy to add new formats
- Consistent output structure
NexMap supports multiple export formats, all generated from a single scan:
{
"scan_info": {
"start_time": "2026-02-05T21:32:45",
"scanner": "nmap",
"version": "7.94"
},
"hosts": [
{
"ip": "192.168.1.1",
"status": "up",
"ports": [...]
}
]
}Tabular format for spreadsheet analysis:
IP,Port,Protocol,State,Service,Version
192.168.1.1,22,tcp,open,ssh,OpenSSH 8.2
192.168.1.1,80,tcp,open,http,nginx 1.18.0Professional web-ready reports with styling and interactivity.
Original Nmap XML format preserved for tool compatibility.
Human-readable summary format for quick review.
Use more threads for large networks:
rustscan -a 10.0.0.0/16 | nexmap -sV --threads 20Combine with aggressive timing:
rustscan -a targets.txt | nexmap -T4 -sV --version-intensity 7Export to all formats at once:
# Use 'all' for convenience
rustscan -a 192.168.1.0/24 | nexmap -A \
--export-format all \
--export-dir ~/security/$(date +%Y%m%d)_scan
# Or specify formats individually
rustscan -a 192.168.1.0/24 | nexmap -A \
--export-format json csv html xml txt \
--export-dir ~/security/$(date +%Y%m%d)_scanBatch convert old scans:
# Convert all XML scans to JSON
for scan in old_scans/*.xml; do
nexmap --file "$scan" --export-format json --export-dir ./modernized/
doneAutomated scanning pipeline:
#!/bin/bash
# Interactive mode auto-enabled, skip checks in CI
rustscan -a $TARGET | nexmap -sV \
--no-check \
--export-format json \
--export-dir /artifacts/scans/Enable verbose mode for debugging:
rustscan -a large_network.txt | nexmap -sV --verboseAdjust thread count for resource-constrained environments:
# Lower threads for stability
rustscan -a targets | nexmap -sV --threads 2- Create a new parser file in
nexmap/parsers/:
from nexmap.parsers.base import BaseParser, ParserFactory
from nexmap.core.models import ScanResult
@ParserFactory.register
class CustomParser(BaseParser):
def can_parse(self, content: str) -> bool:
"""Detect if this parser can handle the content."""
return "custom_signature" in content
def parse(self, content: str) -> ScanResult:
"""Parse content into ScanResult model."""
# Your parsing logic here
return ScanResult(...)- The parser will be automatically registered via the decorator
- Add tests for your parser
- Update documentation
- Edit
nexmap/core/export.py - Add export method following the pattern:
def export_yourformat(self, scan_result: ScanResult) -> Path:
"""Export scan results to YourFormat."""
output_file = self.export_dir / "scan.yourformat"
# Export logic here
return output_file- Register in
export_all()method - Update CLI choices in
cli.py
# Run all tests
pytest
# Run with coverage
pytest --cov=nexmap
# Run specific test file
pytest tests/test_parsers.pyContributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Problem: Nmap is not installed or not in PATH.
Solution:
- Windows: Download from nmap.org and ensure it's added to PATH
- Linux:
sudo apt install nmap(Debian/Ubuntu) orsudo yum install nmap(RHEL/CentOS) - macOS:
brew install nmap
Problem: Certain Nmap scan types (SYN scan, OS detection) require elevated privileges.
Solution:
# Linux/macOS
sudo rustscan -a target | sudo nexmap -A
# Windows (Run PowerShell/CMD as Administrator)
rustscan -a target | nexmap -AProblem: Trying to run NexMap without piping input or specifying a file.
Solution: NexMap requires input via pipe or file:
# β Wrong - no input
nexmap -sV
# β
Correct - piped input (interactive mode auto-enabled)
rustscan -a 192.168.1.1 | nexmap -sV
# β
Correct - file input
nexmap --file scan.xml
# β
Correct - simple stdin parsing
nmap -sV target -oX - | nexmapProblem: Input format not recognized or invalid.
Solution:
- Ensure Nmap XML output format:
nmap ... -oX - - Check that RustScan output is being piped correctly
- Enable verbose mode:
--verbosefor debugging - Verify file content if using
--file
Problem: Cannot write to export directory.
Solution:
# Specify a writable directory
rustscan -a target | nexmap -sV --export-dir ~/scans
# Or fix permissions
chmod 755 /path/to/export/dirIf you encounter issues:
- Run with
--verboseflag for detailed logging - Check that prerequisites are installed (
nmap --version) - Verify input format is valid
- Check GitHub Issues
- Open a new issue with verbose output and error messages
This project is licensed under the MIT License - see the LICENSE file for details.
NexMap is built on the shoulders of giants:
- Rich by Will McGugan - Incredible terminal formatting library
- Pydantic - Robust data validation and settings management
- Nmap by Gordon Lyon (Fyodor) - The industry-standard network scanner
- RustScan - Blazing-fast modern port scanner
- lxml - Powerful XML processing library
- PyYAML - YAML parser and emitter
Special thanks to the security community for feedback and contributions.
Built with β€οΈ for security professionals
Report Bug β’ Request Feature β’ Documentation