One Workflow, Several Ways to Send It

This chapter compares Hoppscotch's request execution paths rather than ranking its clients in the abstract. The question is practical: what does a capability declaration tell us before a request is sent, and when does a real constraint justify moving from the browser to a proxy, extension, native relay, or Agent? The answer helps readers diagnose an unsupported request and choose the smallest execution boundary that can actually honor it.

The request contract from the previous chapter gives the comparison a common denominator. Every path receives a request with intent already expressed—method, URL, headers, parameters, content, authentication, and possibly security or proxy settings. What differs is the environment that must carry that request. A path is not “better” because its capability set is longer. It is better only when the extra capability addresses a real constraint without imposing unnecessary installation, trust, or maintenance cost.

A capability declaration is a boundary, not a promise of magic

Hoppscotch represents relay capabilities in categories such as methods, headers, content, authentication, security, proxy behavior, and advanced options. An interceptor can check whether it can handle a request before executing it. If it cannot, the result is an unsupported-feature error that identifies the boundary. That turns a vague failure into a useful diagnosis: the selected path does not support this kind of content, certificate, proxy, or authentication behavior.

This preflight has two important consequences. First, a request can fail before a target server is contacted. That is a local compatibility result, not an API response. Second, the same request may be valid in the shared data model but invalid for the selected interceptor. The request contract is broader than any one execution implementation. The platform boundary is where the difference becomes visible.

The capability set should still be read as an implementation declaration, not as an independent guarantee. The repository contains compatibility handling, external dependencies, and operating-system-specific behavior. A path may advertise support while an endpoint, certificate chain, proxy, or browser policy creates a further failure. Capability awareness narrows the search; it does not eliminate the need to understand the conditions under which a request succeeds.

The browser is the right default when the problem is ordinary HTTP

The browser path is attractive because it has the lowest activation cost. There is no separate native service to install, no local registration to maintain, and no platform-specific certificate store to configure. For ordinary requests, that simplicity is a genuine capability. The browser interceptor supports common HTTP methods, ordinary text and structured content, and basic, bearer, and API-key authentication. If a public API can be reached under browser rules, the web path keeps the workflow lightweight and easy to share.

That default should not be mistaken for a deficiency. A browser is often the correct owner of the interface, environment editor, response viewer, and test feedback. Adding a native component merely because one exists would increase the system's trust and operational surface without improving the request. The smallest sufficient boundary is usually the most intelligible one.

The limits become decisive when the browser's security model is part of the problem. The browser implementation explicitly has no certificate or proxy capability in the relay contract. It cannot simply decide to attach a client certificate, route through an authenticated proxy, override every restricted header, or reach an arbitrary local service. A CORS error is therefore not necessarily evidence that Hoppscotch's request model is wrong. It may mean that the selected execution environment is enforcing a rule it was designed to enforce.

A useful diagnostic sequence starts with the request's actual constraints. Is the target public and reachable from the browser? Are the headers within the browser's control? Does authentication require only values that can be represented in a normal request? Is there any need for a client certificate, custom CA, proxy authentication, or local network access? If the answer is no, the browser path avoids needless complexity. If the answer is yes, changing the execution boundary becomes a reasoned decision rather than a preference for a different client shell.

Extensions and proxies solve selected browser problems

An extension occupies a middle position. It keeps the main Hoppscotch experience in the browser but uses an extension hook to obtain capabilities that a page does not have on its own. The repository's extension interceptor advertises broader header, content, security, proxy, and local-access support than the browser interceptor. It also contains transport compatibility logic for binary request and response bodies and for different extension versions.

That extra path is valuable when the missing capability is close to the browser boundary. An extension may be enough when the user needs restricted headers or a browser-adjacent request mechanism but does not need the full lifecycle of a native desktop relay. It can preserve a web-first installation and interaction model while adding a controlled integration point.

But an extension is not a transparent upgrade to the browser. It has its own availability and version-detection behavior, its own serialization expectations, and its own binary compatibility cases. A request body that is a Uint8Array, ArrayBuffer, Blob, or File may need to be converted for transport and reconstructed on the response side. The implementation even keeps compatibility hints for older extension versions. That is evidence of a real boundary: the shared request meaning survives, but the representation crossing the boundary may change.

A proxy changes the boundary in a different direction. Instead of asking the browser or an extension to contact the target API directly, Hoppscotch packages the request for a proxy service. The proxy receives a description of the intended URL, method, headers, parameters, body, and selected authentication, performs the outward request, and returns a response that the interceptor decodes.

This can solve a browser-origin problem and can provide a route to endpoints that the page cannot reach directly. It also creates a new dependency and a new compatibility format. The proxy interceptor contains special handling for multipart requests, binary bodies, cookies, and legacy response behavior. Multipart data may need to be placed alongside a serialized description of the request. Binary responses may be represented through encoded data before the common response model can restore their bytes.

The distinction is important. A proxy can be the right answer to “the browser cannot reach this endpoint directly,” but it is not automatically the right answer to “I need native certificate and system integration.” The proxy must support the required body and authentication behavior, the user must accept the service boundary, and the path must be available and correctly configured. It solves a selected reachability problem by moving execution to another service; it does not make the browser a native client.

Native and Agent paths trade reach for responsibility

Native execution expands the request surface substantially. The desktop relay advertises support for a broader set of content forms, security settings, proxy options, redirects, cookies, and advanced transport behavior. The native relay package describes client certificates, custom root certificates, certificate validation control, proxy authentication including NTLM, cancellation, progress, and response timing. These features matter for enterprise APIs, internal services, mutual TLS, local development endpoints, and debugging cases where browser policy is the limiting factor.

The price is a larger system boundary. Native execution depends on the operating system, native libraries, certificate material, proxy configuration, and the behavior of a pinned relay implementation. A failure can come from any of those layers. A certificate may be present but mismatched. A proxy may require authentication. A local API may be reachable from the operating system but not from the expected interface. A feature advertised by the native path may still encounter platform-specific behavior. More control means more conditions that must be configured and observed.

The Agent offers a different arrangement of the same basic idea. The web application remains the main user-facing surface, while a local Agent runs a request relay and exposes a loopback boundary to the application. The Agent and native interceptors advertise capabilities for client certificates, custom CA certificates, host and peer verification, proxy configuration, and local access. Domain-specific settings let a user apply different controls to different API hosts instead of treating the entire machine as one undifferentiated transport context.

This arrangement is useful when the user needs local or native access but wants to retain a browser-centered workflow. It is also a reminder that “desktop” and “Agent” are not interchangeable labels. A desktop shell owns more of the application environment. An Agent supplements a web application through a separate local service and registration relationship. The request contract can be shared, while the ownership of trust, persistence, and lifecycle differs.

Cookies illustrate why the distinction matters. The native and Agent paths can participate in a shared cookie path where the platform allows it, while the web platform's feature flags differ. An isolated run can explicitly opt out of cookie use even on a cookie-enabled platform. Therefore, selecting a more capable path may change not only where bytes travel but also which local state is attached to them. That is a functional and security decision, not merely a performance setting.

Match constraints to paths, not labels

The decision is clearer when expressed as scenarios. For a public JSON API with ordinary authentication and no browser restriction, use the browser path. It has the least setup and the smallest additional trust boundary. If a browser-origin or restricted-header problem blocks direct execution, consider an extension or proxy, then verify that the chosen workaround supports the body, authentication, cookies, and response format the request actually needs.

For an API requiring a client certificate, custom CA bundle, proxy authentication, local access, or explicit certificate-verification controls, a native or Agent path is the natural candidate. The choice between them depends on where the surrounding application should live and who should own the local configuration. A desktop user may want the native shell to own the transport. A web user may want the Agent to add those capabilities without abandoning the web interface.

A request can also be hybrid in its needs. One collection may contain a public request that works in the browser and an internal request that requires the Agent. That does not mean the entire workflow must move to the most privileged path. It means the user should understand which requests need which boundary and whether the application makes the active interceptor choice explicit. The repository's interceptor service registers paths and selects an active one; the source does not establish a universal automatic fallback that silently migrates every unsupported request to another relay.

flowchart LR A["Request with ordinary public HTTP needs"] --> B{"Browser can honor constraints?"} B -->|"Yes"| C["Browser relay"] B -->|"No: CORS or restricted headers"| D{"Selected workaround is enough?"} D -->|"Extension fits"| E["Extension path"] D -->|"Proxy fits"| F["Proxy service"] D -->|"No: certificate, proxy, or local access"| G["Native or Agent path"] C --> H["Response or typed boundary error"] E --> H F --> H G --> H H --> I["Same workflow, different capability and responsibility"]

The important word in this decision is “fits.” An extension or proxy is not automatically safer or simpler than native execution; it is appropriate when its boundary matches the problem. Native execution is not automatically better because it supports more features; it is appropriate when those features are necessary and the user can accept the installation and trust implications. A request that succeeds through the browser has not proved that the native path is wrong. A request that fails in the browser has not proved that the native path is required. The capability and failure information must be read together.

This comparison also explains why a single shared request contract is valuable. Without it, each path would force users to learn a different request model, and moving from browser to native would mean rebuilding the artifact. With the contract, the artifact can travel while the execution boundary changes. The differences do not disappear; they become explicit enough to reason about.

The next synthesis can now ask a more disciplined question than “which client is best?” It can ask what remains invariant across the paths, what changes at each boundary, and which combination of capability, convenience, trust, and operating cost is acceptable for a particular request.

References