Back Home

Post Detail

2026.09.11

6 min read

engineering / browser / chrome-extension / devtools

Building RequestKit: The Hard Part Is Explaining What a Rule Affects

A small Chrome extension raises useful product questions: which host a header rule affects, what a switch should preserve, and why saving configuration is not the same as applying it.

RequestKit scope diagram separating the page address, request destination, and per-site rules

A tool for changing request headers seems to need only two inputs: a name and a value.

The harder questions come afterward. Does the setting affect this tab or every request to a host? Does it follow me to another site? If I disable a profile and enable it again, will a rule I deliberately turned off stay off?

Those are the boundaries I care about in RequestKit. A developer tool can be small, but its behavior should be predictable.

The page address is not the request destination

Consider an admin application:

text
Open page          https://admin.example.com
Request it makes   https://api.example.com/orders

Should a profile for admin.example.com also affect the API request? Either behavior could support a coherent product. The important decision is to choose one and make the interface agree with execution.

RequestKit's Per site mode matches the exact destination hostname. The API request above needs its own api.example.com profile. The active tab helps the popup choose which site to edit; it does not bring every third-party request from that page into the same profile. Matching implementation

For a profile named api.example.com:

RequestIncluded?
https://api.example.com/ordersYes
https://api.example.com:8443/ordersYes; the port does not change the hostname
https://v2.api.example.com/ordersNo; a subdomain has its own profile
https://example.com/?next=api.example.comNo; text in a query is not the destination host

“Only this site” is therefore incomplete copy. “Requests to this exact hostname” gives the user a much better prediction.

A switch should pause configuration without rewriting it

RequestKit has two mutually exclusive modes: Per site and All sites, with the latter covering HTTP/HTTPS sites. Each retains its own configuration. Switching modes changes which configuration is active.

Within a profile, the profile switch and individual rule switches have separate jobs. Suppose rules A and B are enabled while C is disabled. Turning the profile off and back on should restore that combination.

Setting every rule's enabled field to false would erase the user's choices. A better model stores both levels independently and applies a rule only when both allow it.

RequestKit's site manager with example.com demonstration profiles

The project's public demonstration image uses sample domains and header values.

This distinction applies well beyond browser extensions. Pausing a notification group or a task collection should usually preserve the preferences inside it.

Saving is an execution process

Seeing a new value in the interface only proves that the editor accepted the change. RequestKit must persist the configuration and translate it into rules the browser actually applies.

It uses Chrome's declarativeNetRequest API: the extension declares rules and the browser applies them during requests. Dynamic rules persist across browser sessions. Completed requests are not changed retrospectively, so verification must inspect a new request. Chrome documentation

Storage and rule application can fail separately. If storage succeeds but synchronization fails, the interface and browser may disagree about what is active.

The implementation attempts to restore the previous configuration and synchronize the old rules. A failed recovery has a distinct error state. This is not a database transaction, and it does not establish perfect atomicity across both systems. The useful property is that failure is visible instead of being reported as a successful save. Save and recovery implementation

An editor must remember what it is editing

Open a rule for site A, switch the surrounding view to site B, then save. The edit should still target A.

RequestKit captures the target when editing begins and checks the original rule before applying the change. A conflicting edit from another window should not be silently overwritten. Target and conflict checks

The reusable lesson is a short set of questions: is the target explicit, are earlier choices preserved, and can the user understand the state after a failure?

Those questions are where I would start the next small tool, before deciding how many controls it needs.

The repository includes an installation guide. Configuration stays in the current browser and there is no account system. The implementation discussed here was inspected on September 11, 2026.