A development-time API request/response network behavior simulator for frontend applications.
⭐ Featured in JavaScript Weekly (Issue #773)
It intercepts the global fetch function and simulates real-world instability directly in the browser.
This tool does not mock APIs. It modifies how real API requests and responses behave before they reach your UI.
You can simulate:
- Latency (slow API responses)
- Packet loss (random request failures)
- Automatic retries
- Stale or out-of-order responses
- Burst control (concurrency limits)
- Bandwidth throttling
This helps you test UI resilience under realistic production conditions.
Demo
The demo shows a dashboard running with multiple instability rules enabled.
Simulated behaviors:
- Artificial response delay
- Random request failure
- Automatic retry attempts
- Limited concurrent requests
- Out-of-order responses
The console groups each request lifecycle so you can observe:
- When a request started
- Which rules were applied
- Whether it retried
- When it resolved or failed
Why This Exists
Most frontend applications are built and tested under ideal conditions:
- Instant responses
- No failures
- Perfect response ordering
- Unlimited concurrency
Production is different.
Real users experience:
- Slow APIs
- Random failures
- Retried requests
- Out-of-order responses
- Race conditions
- Aborted requests
Many UI bugs only appear under instability.
This tool makes those failures reproducible during development.
What It Actually Does
The simulator wraps the global fetch function.
Instead of:
UI → fetch → network → response
Execution becomes:
UI → fetch → simulator → rules → real fetch → modified response → UI
It operates strictly at the HTTP request/response layer inside JavaScript.
It does not simulate:
- TCP packets
- DNS failures
- OS-level network issues
- Browser DevTools throttling
It modifies how API requests behave before your application receives the response.
Installation
npm install fetch-network-simulator
Initialization (Important)
The simulator must be enabled at your application entry point.
Place it in:
main.jsmain.jsxindex.js- Or the top-level bootstrap file
Do not initialize it inside components or request utilities.
Example:
import { enableNetworkSimulator } from "fetch-network-simulator"; if (process.env.NODE_ENV === "development") { enableNetworkSimulator({ debug: true, // optional: structured request lifecycle logs latency: { enabled: true, delayMs: 1500 }, packetLoss: { enabled: true, lossRate: 0.3 }, retry: { enabled: true, maxAttempts: 3, retryDelayMs: 200 }, staleResponse: { enabled: true, staleProbability: 0.5 }, burstControl: { enabled: true, maxConcurrent: 1 }, networkSpeed: { enabled: true, kbps: 500 } }); }
Why at the root?
Because the simulator wraps the global fetch.
If initialized late, earlier requests may bypass interception.
Disable
import { disableNetworkSimulator } from "fetch-network-simulator"; disableNetworkSimulator();
Debug Mode
Enable structured request lifecycle logs:
debug: trueWhen enabled, the simulator groups logs in the console for each request.
Logged lifecycle events include:
- Request start
- Applied rules
- Artificial delay injection
- Retry attempts
- Failures
- Final resolution
- Response ordering behavior
This helps identify:
- Race conditions
- Incorrect retry handling
- State overwrites
- Missing loading or error states
If debug is not set or false, the simulator runs silently.
Recommended pattern:
if (process.env.NODE_ENV === "development") { enableNetworkSimulator(config); }
Architecture Overview
The engine uses a deterministic rule execution pipeline.
fetch
↓
simulateFetch
↓
RuleExecutor
↓
Rules (lifecycle hooks)
↓
real fetch
Built-in Rules
LatencyRulePacketLossRuleRetryRuleStaleResponseRuleBurstControlRuleNetworkSpeedRule
Each rule implements lifecycle hooks:
beforeRequest(context)afterResponse(context, response)onError(context, error)
Design characteristics:
- Deterministic rule ordering
- Session-scoped rule lifecycle
- No duplicate rule instantiation
- Isolated side effects
- Extensible rule model
Senior developers can extend the engine by implementing custom rules using the same lifecycle contract.
Upcoming Features
Request Cancellation Simulation
Support for simulating aborted requests using AbortController.
This will help test:
- Rapid navigation
- Search-as-you-type cancellation
- React effect cleanup correctness
- Memory leak prevention
Packet Ordering / Response Reordering
Real systems do not guarantee response order.
Upcoming support will simulate:
- Earlier requests resolving later
- Faster later requests
- Delayed response injection
This exposes:
- Race conditions
- Stale state overwrites
- Incorrect request deduplication
Example failure pattern:
Request A → slow Request B → fast
Response B updates UI Response A arrives later and overwrites newer state
Scope & Limitations
- Browser-only
- Intercepts
fetchonly - API request/response level simulation
- Not transport-layer packet simulation
- Development-time tool
It does not replace:
- API mocking frameworks
- Service worker simulation
- Backend emulators
It modifies real API calls at the JavaScript layer.
Repository Structure
core/ → Published npm package (engine + rules)
ui/ → Visual control layer (in progress)
The npm package includes only the core engine.
The ui/ directory is an experimental layer intended for:
- Real-time rule toggling
- Preset network profiles
- Timeline visualization
- Interactive debugging panel
Intended Use Cases
- UI stress testing
- Race condition debugging
- Resilience validation
- Teaching async request behavior
License
MIT
