apollo-upload-client: Apollo Link for GraphQL File Uploads
A terminating Apollo Link for Apollo Client that fetches a GraphQL multipart request if the GraphQL variables contain files (by default FileList, File, or Blob instances), or else fetches a regular GraphQL POST or GET request (depending on the config and GraphQL operation).
At a glance
- What is it?
- apollo-upload-client is a terminating Apollo Client 4 Link that sends multipart requests when GraphQL variables contain FileList, File, or Blob values. It suits applications whose server implements the GraphQL multipart request specification.
- Who is it for?
- Adopt apollo-upload-client when Apollo Client 4 is already in use and the GraphQL server implements the multipart request specification. Do not choose it for a JSON-only server or an Apollo Client release outside the declared peer range.
- Can I use it commercially?
- Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
- Is it still maintained?
- Yes. The repository last received commits 86 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
apollo-upload-client targets Apollo Client file mutations
apollo-upload-client addresses the mismatch between standard GraphQL variables and browser upload objects. GraphQL transports normally carry variables as JSON, but an uploaded browser resource is represented by a `FileList`, `File`, or `Blob`. This package detects those values in query or mutation variables and sends a GraphQL multipart request. If no supported file is present, it sends a regular GraphQL POST or GET request, depending on configuration and the operation.
The package is intended for applications that already use Apollo Client 4 and need file uploads in mutations. It is not a complete upload service. The README requires the GraphQL server to implement the GraphQL multipart request specification and states that resolvers must handle uploads correctly. Installing this client package does not add server-side schema, storage, or resolver support.
Its runtime declaration is explicit. `package.json` supports Node.js `^22.13.0 || ^24.0.0 || >=26.0.0`. Its peer dependencies are `@apollo/client` `^4.0.0`, `graphql` `^16.0.0 || ^17.0.0`, and `rxjs` `^7.3.0`. This makes the project a focused choice for a modern Apollo Client stack rather than a compatibility layer for older client generations.
UploadHttpLink chooses multipart or ordinary GraphQL transport
`UploadHttpLink` is the package's terminating Apollo Link, meaning it performs the GraphQL request instead of passing that responsibility to another request-sending link. Apollo Client permits only one terminating link. If an application already uses `HttpLink` for this purpose, the README instructs developers to remove it and construct `ApolloClient` with `UploadHttpLink`. For Apollo Client awareness features, the README says to compose `ClientAwarenessLink` before the terminating link.
The request choice happens at the link layer. When the GraphQL variables contain an extractable file, `UploadHttpLink` follows the multipart upload path. Without one, it uses the ordinary GraphQL request path. The package description identifies POST or GET behavior as dependent on configuration and the GraphQL operation, allowing one Apollo client to carry both conventional queries and upload mutations.
The repository exposes two focused helpers alongside the link. `isExtractableFile.mjs` handles file detection, and `formDataAppendFile.mjs` handles appending an extracted file to form data. The package depends on `extract-files` `^14.0.0` for extraction. File values may occur anywhere in the GraphQL variables, so the package does not require uploads to remain at a fixed top-level property. The GraphQL schema and server resolver still need matching upload types.
Installing apollo-upload-client with supported peer packages
The README lists npm as the installation method. Install `apollo-upload-client`, then polyfill any globals required by the link that are absent from the browser, React Native, Node.js, or server-side rendering environment.
npm install apollo-upload-clientThe command adds the package to the consuming application, but it does not install peer dependencies automatically. The application must provide compatible versions of `@apollo/client`, `graphql`, and `rxjs`. The README does not provide an older Apollo Client setup, so code written against an earlier major release should not be assumed to work.
The package also has no main index module. `package.json` exposes named ECMAScript module subpaths, including `./UploadHttpLink.mjs`, `./isExtractableFile.mjs`, `./formDataAppendFile.mjs`, and `./package.json`. Imports should use one of those exported paths. TypeScript projects using JavaScript module types also need to follow the README's `allowJs`, `maxNodeModuleJsDepth`, `node16`, or `nodenext` guidance.
Sending a first File through an Apollo mutation
A basic upload places a browser `File` into the mutation variables. The GraphQL document must declare the expected upload variable, and the selected file must be passed under that same property. The README's React example validates the input, confirms that `files?.[0]` exists, and sends it as `variables.file`.
const mutation = gql`
mutation ($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;In the documented component, `useMutation` comes from `@apollo/client/react`, while `gql` comes from `@apollo/client`. A single-file input triggers `mutate({ variables: { file: files[0] } })` only when the browser reports that the input is valid and contains a file. The response selection contains `uploadFile.success`, so the application can react to the mutation result without requesting unrelated fields.
This example defines the GraphQL client operation, but it does not define a server schema or upload resolver. The `Upload` type and `uploadFile` field shown here must exist on the configured GraphQL API and follow the multipart request specification. A local React example will therefore work only against a compatible server implementation.
FileList, File, and Blob values have different upload shapes
The README documents three accepted browser value shapes. A `FileList` can be assigned directly to a plural mutation variable. A single `File` can be assigned to a singular variable. A `Blob` can also fill the singular variable, although the README warns that this approach uses the default upload filename `blob`. The package does not require the application to normalize every input into one wrapper object before calling Apollo Client.
new File(
[value],
// Custom file name.
"text.txt",
{
type: "text/plain",
},
);Use this `File` construction instead of an unnamed `Blob` when the server needs a specific filename. That is a meaningful operational distinction: multipart encoding can carry the binary value, but it does not decide where the server stores the file or what naming policy the application enforces.
The examples also show that files can be nested anywhere in variables because the extraction library traverses the variable data. The README does not document custom extraction callbacks or per-operation extraction rules. Developers should not assume unsupported object types will be recognized without consulting the exported extraction behavior and tests.
UploadHttpLink has server and runtime boundaries
The most direct failure case is a server that accepts only ordinary JSON GraphQL requests. Adding `UploadHttpLink` cannot make that endpoint interpret multipart file fields. The README requires server support for the multipart request specification and correct resolver behavior, but it does not document a compatibility mode that converts an unsupported server back into ordinary JSON uploads.
There are also client constraints. The declared Apollo Client range starts at `^4.0.0`, while the package does not claim support for Apollo Client 3. The supported Node.js versions are narrow by design, and browser targets follow the Browserslist query `> 0.5%, not OperaMini all, not dead`. Missing globals such as the browser file and form-data primitives required by the implementation must be supplied when they are absent.
Link composition is another common error. Stacking `UploadHttpLink` and `HttpLink` as separate terminating senders conflicts with Apollo Client's model described in the README. Awareness or other non-terminating links belong before `UploadHttpLink`. The repository layout includes tests for the link and its helpers, but the README does not document retry, progress, cancellation, or resumable upload behavior, so this package should not be presented as providing those features.
HttpLink is simpler when GraphQL variables never contain files
The practical alternative is Apollo Client's regular `HttpLink` when the server and operations require only standard GraphQL requests. The README describes `HttpLink` as an example of an existing terminating link, but it does not state that `HttpLink` performs `apollo-upload-client`'s multipart file extraction. The meaningful difference is transport behavior: `apollo-upload-client` conditionally converts supported file-bearing variables into a multipart request, while ordinary JSON operations continue through the regular GraphQL path.
Choose plain `HttpLink` when file uploads are absent or are handled outside GraphQL. Choose `UploadHttpLink` when one Apollo Client must support both ordinary operations and mutations containing `FileList`, `File`, or `Blob` values, with a compatible server behind it. Choosing `apollo-upload-client` without implementing the multipart server contract adds a client dependency but does not remove the server requirement.
The package design also changes imports. Consumers use a deep ECMAScript module export such as `apollo-upload-client/UploadHttpLink.mjs`, not a root package entry. Migration therefore involves checking both Apollo Link composition and module resolution, rather than only changing a request URL or adding a middleware option.
Release history and MIT upgrade boundaries
The repository is not archived, and the last push was on 2026-07-29. The listed releases include v20.0.0 on 2026-07-29, v19.0.0 on 2025-08-29, and v18.0.1 on 2023-10-24. The release dates and current package version make version checking a concrete part of an upgrade, but the README does not provide a formal upgrade guide for every major release.
`package.json` identifies the project as MIT licensed. It publishes three runtime files and marks the package as having no side effects. It also uses an `exports` map, so bundler behavior and deep imports should be checked after upgrading. A consuming application that imported paths outside the declared export map can fail even if the package version resolves correctly.
Before upgrading an established client, compare the old peer dependency set with Apollo Client 4, supported Node.js versions, graphql 16 or 17, and rxjs 7.3 or later. Then confirm that the GraphQL server still accepts the multipart request format and that resolvers still handle the uploaded values. The client release can be upgraded, but the deployment is incomplete if only the browser package changes.
Editorial conclusion
Adopt apollo-upload-client when Apollo Client 4 is already in use and the GraphQL server implements the multipart request specification. Do not choose it for a JSON-only server or an Apollo Client release outside the declared peer range. Before replacing HttpLink, verify server upload handling, supported runtime versions, required globals, and the package's deep ECMAScript module imports.
Frequently asked questions
How do I install apollo-upload-client?
Run `npm install apollo-upload-client`, then polyfill any globals missing from the client and server environments. The application must also provide compatible peer dependencies.
Does apollo-upload-client send files as multipart requests?
Yes. The README says it sends a GraphQL multipart request when variables contain `FileList`, `File`, or `Blob` instances. The server must implement the multipart request specification and handle uploads in resolvers.
Can I use UploadHttpLink with HttpLink at the same time?
No. Apollo Client can have only one terminating link that sends requests. Replace a terminating `HttpLink` with `UploadHttpLink`, composing non-terminating links such as `ClientAwarenessLink` before it.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/jaydenseric-apollo-upload-client)Was this useful?