fastify-reply-from
Fastify plugin that forwards the current HTTP request to another server, with pluggable HTTP/1.1, HTTP/2, and undici transports.
Repository Health
Technical Analysis
@fastify/reply-from decorates Fastify’s reply object with a from() method so route handlers can forward the current request to an upstream server and stream the response straight back to the client. It functions as a lightweight reverse-proxy building block for Fastify applications, without requiring a separate proxy layer like nginx or HAProxy in front of the app.
Under the hood it can transport requests over undici (the default, for maximum throughput), Node’s native http/https module, or HTTP/2, and it automatically switches to undici’s BalancedPool for round-robin load balancing when given multiple base origins. It ships automatic retry logic for idempotent methods on 503 responses, pluggable header rewriting hooks, and typed errors for every failure mode, making it a common building block for API gateways, backend-for-frontend services, and incremental service migrations built on Fastify.
What You Get
- A
reply.from(source, opts)decorator for forwarding the current request to an upstream server - Pluggable transport layer: undici (default), Node’s http/https module, or HTTP/2
- Automatic retry-on-503 logic for idempotent methods, with a customizable retryDelay handler
- Header rewriting hooks (rewriteHeaders, rewriteRequestHeaders) plus response/error interception (onResponse, onError)
- Load-balanced multi-origin forwarding via undici’s BalancedPool when base is given an array of origins
- Unix domain socket forwarding via unix+http:// and unix+https:// URL schemes
- Hand-maintained TypeScript type definitions with compile-time type tests (tstyche)
Common Use Cases
- Building a lightweight API gateway that forwards requests to internal microservices
- Implementing a backend-for-frontend that load-balances across multiple backend origins
- Proxying a subset of routes to a new backend during an incremental service migration
- Bridging HTTP/1.1 clients to an HTTP/2 upstream service, or vice versa
Under The Hood
Architecture
index.js decorates the Fastify reply with from(), which delegates to buildRequest() in lib/request.js. That function selects one of three transport implementations — handleHttp2Req, handleUndici, or handleHttp1Req — based on plugin options, all exposed through a uniform request(opts, callback) interface that abstracts over Node’s http/https, undici’s Pool/BalancedPool, and raw http2 sessions. Retry behavior is layered on top via createRequestRetry(), which wraps whichever transport was selected with a getDefaultDelay/retryDelay closure that reschedules failed idempotent requests. URL building and header manipulation are factored into lib/utils.js (buildURL, stripHttp1ConnectionHeaders, filterPseudoHeaders, getConnectionHeaders), and typed FST_REPLY_FROM_* errors are centralized in lib/errors.js on top of @fastify/error. The whole plugin is registered through fastify-plugin as a single encapsulated context with an onClose hook that tears down agents, pools, and HTTP/2 clients — so the transport-selection function in buildRequest is the one abstraction every retry and error-mapping path depends on, since they all assume the same (err, res) callback shape regardless of which transport is active.
Tech Stack
Plain CommonJS JavaScript with no build step, targeting Fastify 5.x as a peer via fastify-plugin ^6. Runtime dependencies are undici ^7 (default HTTP client, also used for BalancedPool and ProxyAgent), @fastify/error ^4 for typed errors, toad-cache ^3 (LruMap) for URL-parse caching, fast-querystring ^1 and fast-content-type-parse ^3 for performance-sensitive parsing, and end-of-stream ^1 for HTTP/2 stream cleanup. The test stack uses Node’s built-in test runner under c8 ^12 with a --100 coverage gate, tstyche ^7 for compile-time type tests against the hand-written type definitions, neostandard/eslint ^9 for linting, and nock ^14 plus proxy ^4 for HTTP mocking.
Code Quality The test suite spans over 100 files, each targeting one specific behavior or regression — including named CVE regression tests such as fix-GHSA-2q7r-29rg-6m5h, fix-GHSA-v2v2-hph8-q5xp, and fix-GHSA-v574-6498-x57v — run through Node’s native test runner with c8 enforcing full statement, branch, function, and line coverage. Errors are explicit, typed FST_REPLY_FROM_* classes built with @fastify/error rather than generic throws, and transport-level error codes (ECONNRESET, UND_ERR_SOCKET, UND_ERR_CONNECT_TIMEOUT) are mapped explicitly instead of being swallowed. Naming is consistently camelCase, coverage-ignore comments are used sparingly and only for platform-specific unreachable branches such as Windows unix-socket paths, and both eslint and tstyche run as part of CI.
API Design
reply.from(source, opts) is a single decorator with sensible defaults — calling it with no arguments forwards the current request path verbatim to whichever base was configured at registration. Every extension point (rewriteHeaders, rewriteRequestHeaders, onResponse, onError, getUpstream, queryString, retryDelay) is a plain function that can be omitted entirely, so a minimal integration is one fastify.register() call plus one reply.from() call in a route handler. The RetryDelay callback exposes a getDefaultDelay escape hatch so custom retry logic never has to fully reimplement the built-in behavior. Some options interact non-obviously — passing an undici instance, a proxy, or an array base each silently selects a different internal code path — and there is no async/await-native variant of reply.from(), though that mirrors Fastify’s own decorator conventions. Type definitions are comprehensive and kept in sync by hand via module augmentation of FastifyReply.
Used by 2 apps in this directory
Activepieces
Automation · AI Assistants
Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.