Contributing
Architecture guide
Learn how Netlytics is structured internally and how the components work together.
Overview
Netlytics is organized into focused modules, each handling a specific aspect of connectivity detection:
connectivity.ts— Core connectivity checking with HTTP probeswatch-connectivity.ts— Event-based watching with validationlatency.ts— Latency measurement utilitiesconnection-type.ts— Network Information API integrationutils.ts— Shared utility functionsconstants.ts— Default configuration valuestypes.ts— TypeScript type definitions
Core Components
Connectivity Checking (connectivity.ts)
The checkConnectivity() function is the core of Netlytics. It:
- Probes multiple URLs — Uses a list of reliable endpoints (defaults include Google, Cloudflare, etc.)
- Validates with real requests — Makes actual HTTP GET requests with CORS support
- Handles timeouts — Each probe has a configurable timeout (default: 5 seconds)
- Requires successes — Can be configured to require multiple successful probes
- Returns comprehensive results — Includes online status, connection type, network quality, and latency
Watching Connectivity (watch-connectivity.ts)
The watchConnectivity() function provides continuous monitoring:
- Subscribes to events — Listens to browser
online/offlineevents - Validates with probes — Every event is confirmed with an actual HTTP probe
- Mobile fallbacks — Uses polling and visibility-change handling on mobile when events don't fire
- Debouncing — Prevents rapid-fire checks when coming back online
- Returns unsubscribe — Clean function to stop watching
Latency Measurement (latency.ts)
The measureLatency() function:
- Samples multiple requests — Makes multiple probes to get accurate RTT
- Averages results — Returns the average latency from successful samples
- Handles failures — Returns
nullif all samples fail
Connection Type Detection (connection-type.ts)
Uses the Network Information API when available:
- Reads from API — Accesses
navigator.connectionornavigator.mozConnection - Normalizes values — Converts API values to consistent types
- Fallback handling — Returns
"unknown"when API is unavailable
Design Decisions
Why Multiple Probe URLs?
Using multiple URLs ensures reliability:
- If one endpoint is down, others can still succeed
- Different CDNs may have different availability
- Reduces false negatives from single-point failures
Why Validate Events?
Browser online/offline events are unreliable:
- They often fire when connected to WiFi without internet
- Mobile browsers may not fire them consistently
- They don't guarantee actual internet connectivity
Netlytics validates every event with a real HTTP probe to ensure accuracy.
Why Polling on Mobile?
Mobile browsers have inconsistent event behavior:
- Safari on iOS may not fire events reliably
- Some Android browsers have delays
- Tab visibility changes aren't always detected
Polling provides a reliable fallback for mobile scenarios.
File Structure
src/
├── index.ts # Main exports
├── connectivity.ts # checkConnectivity()
├── watch-connectivity.ts # watchConnectivity()
├── latency.ts # measureLatency()
├── connection-type.ts # getConnectionType(), getNetworkQuality()
├── constants.ts # Default values
├── types.ts # TypeScript types
└── utils.ts # Shared utilities
Contributing
When contributing to Netlytics:
- Follow the existing patterns — Keep code style consistent
- Add tests — All new features should have tests
- Update types — Keep TypeScript types in sync
- Document changes — Update relevant documentation
See How to contribute for more details.