Skip to content

How to attach additional data when using hooks #695

@makbol

Description

@makbol

Hi! 👋

I would like to measure the duration of HTTP requests — from the moment they are initiated to the point the Response is received (excluding .json() parsing). The goal is to include this metadata (e.g. duration) in a way that can be accessed later, ideally without breaking the native Response API or Ky’s clean structure.

I’ve explored several approaches — attaching timestamps to options in beforeRequest, wrapping Ky methods, reconstructing Response objects, or returning custom { data, duration } shapes — but none of them provide a clean, reliable solution that maintains type safety, Ky compatibility, and performance.

As an example of the problem, consider this setup:

const api = ky.create({
  hooks: {
    beforeRequest: [
      (_request, options) => {
        options._start = performance.now();
      }
    ],
    afterResponse: [
      (_request, options, response) => {
        const start = options._start;
        const duration = start ? performance.now() - start : undefined;
    
        // But now what? There's no safe or standard place to store `duration`
        // - Mutating the response (e.g. `response.duration = ...`) feels wrong
        // - Replacing the response with a custom object breaks compatibility
        // - Wrapping all calls loses Ky's chaining and hook benefits
    
        return response;
      }
    ]
  }
});

Related

I found #329, which discusses accurate request timing, but my use case is more lightweight — I just want a rough request duration for basic monitoring/logging.

My question

Is there an officially supported or idiomatic way to propagate lightweight metadata like duration across Ky’s lifecycle — from beforeRequest to afterResponse, and ideally to the consumer?
If not, would you consider exposing a context or metadata mechanism to enable this kind of need?

Thanks again for maintaining Ky — it’s a fantastic library and I’d love to keep using it in a clean and maintainable way.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions