{"id":18400,"library":"graphql-upload","title":"graphql-upload","description":"Middleware and a GraphQL Upload scalar for handling file uploads via multipart requests in Node.js GraphQL servers (Express, Koa, Apollo). Version 17.0.0 is ESM-only, requires Node.js ^18.18.0 || ^20.9.0 || >=22.0.0, and graphql ^16.3.0. Key differentiators: implements the GraphQL multipart request spec, supports deduplication of files across variables, streams files to cloud storage or filesystem, and provides both middleware functions and a low-level processRequest function for custom integrations. Released actively with breaking changes in major versions.","status":"active","version":"17.0.0","language":"javascript","source_language":"en","source_url":"https://github.com/jaydenseric/graphql-upload","tags":["javascript","graphql","upload","file","multipart","request","server","middleware","koa"],"install":[{"cmd":"npm install graphql-upload","lang":"bash","label":"npm"},{"cmd":"yarn add graphql-upload","lang":"bash","label":"yarn"},{"cmd":"pnpm add graphql-upload","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"peer dependency required for GraphQL scalar Upload integration","package":"graphql","optional":false},{"reason":"processes multipart request bodies; security-critical dependency","package":"busboy","optional":false},{"reason":"manages temporary file streams and cleanup","package":"fs-capacitor","optional":false}],"imports":[{"note":"ESM-only since v16; uses deep imports. CommonJS require not supported.","wrong":"import { graphqlUploadExpress } from 'graphql-upload'","symbol":"graphqlUploadExpress","correct":"import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs'"},{"note":"ESM-only since v16; uses deep imports.","wrong":"import { graphqlUploadKoa } from 'graphql-upload'","symbol":"graphqlUploadKoa","correct":"import graphqlUploadKoa from 'graphql-upload/graphqlUploadKoa.mjs'"},{"note":"Default export from the module; named export only from type definitions in TypeScript.","wrong":"import { GraphQLUpload } from 'graphql-upload'","symbol":"GraphQLUpload","correct":"import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'"},{"note":"ESM-only deep import; no CommonJS require available.","wrong":"const processRequest = require('graphql-upload/processRequest.mjs')","symbol":"processRequest","correct":"import processRequest from 'graphql-upload/processRequest.mjs'"},{"note":"TypeScript type import only; not a runtime export.","wrong":"import { FileUpload } from 'graphql-upload'","symbol":"FileUpload","correct":"import type { FileUpload } from 'graphql-upload/processRequest.mjs'"}],"quickstart":{"code":"import express from 'express';\nimport { createHandler } from 'graphql-http/lib/use/express';\nimport { buildSchema } from 'graphql';\nimport graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs';\nimport GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs';\n\nconst schema = buildSchema(`\n  scalar Upload\n\n  type File {\n    filename: String!\n    mimetype: String!\n    encoding: String!\n  }\n\n  type Mutation {\n    singleUpload(file: Upload!): File!\n  }\n\n  type Query {\n    _: Boolean\n  }\n`);\n\nconst rootValue = {\n  singleUpload: async (parent, { file }) => {\n    const { filename, mimetype, encoding, createReadStream } = await file;\n    const stream = createReadStream();\n    // Process stream (e.g., save to disk or cloud)\n    // For demo, just discard the stream\n    stream.resume();\n    return { filename, mimetype, encoding };\n  }\n};\n\nconst app = express();\napp.use('/graphql', graphqlUploadExpress({ maxFileSize: 10000000, maxFiles: 10 }));\napp.all('/graphql', createHandler({ schema, rootValue }));\napp.listen(4000, () => console.log('Server running on port 4000'));","lang":"javascript","description":"Express server with graphql-upload middleware handling a single file upload mutation using the Upload scalar."},"warnings":[{"fix":"Switch to import syntax and use deep imports like import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs'.","message":"Since v16, the package is ESM-only in .mjs files and no longer supports CommonJS require(). Deep imports must be used.","severity":"breaking","affected_versions":">=16.0.0"},{"fix":"Use deep imports for each module (e.g., 'graphql-upload/GraphQLUpload.mjs').","message":"In v14, the main index module was removed. Imports from 'graphql-upload' no longer work.","severity":"breaking","affected_versions":">=14.0.0"},{"fix":"Update type imports: import type { GraphQLUpload } from 'graphql-upload/GraphQLUpload.mjs'.","message":"GraphQLUpload type import path changed. Previously import type { GraphQLUpload } from 'graphql-upload/Upload.mjs' now must be from 'graphql-upload/GraphQLUpload.mjs'.","severity":"deprecated","affected_versions":">=17.0.0"},{"fix":"Ensure to await the file promise and handle stream errors: const { createReadStream } = await file;","message":"File upload promise must be awaited in resolvers, otherwise the server may send a response before the upload completes, causing client disconnection.","severity":"gotcha","affected_versions":">=0.0.0"},{"fix":"Upgrade to graphql-upload >=15.0.0 which uses busboy v1 with the fix.","message":"The busboy dependency used for multipart parsing had a vulnerability (CVE-2022-24434) affecting versions <15.0.0 of graphql-upload.","severity":"security","affected_versions":"<15.0.0"},{"fix":"Update any error handling to match the new busboy error messages.","message":"In v15, busboy updated to v1, which changed some error messages. Code relying on exact error strings may break.","severity":"breaking","affected_versions":">=15.0.0"},{"fix":"Ensure os.tmpdir() is writable and monitor disk space.","message":"The process must have read and write access to os.tmpdir() and sufficient disk space for concurrent uploads.","severity":"gotcha","affected_versions":">=0.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Use deep imports: import GraphQLUpload from 'graphql-upload/GraphQLUpload.mjs'","cause":"Using import from the package root (e.g., import { GraphQLUpload } from 'graphql-upload') which is not exported since v14.","error":"Cannot find module 'graphql-upload'"},{"fix":"Use default import: import graphqlUploadExpress from 'graphql-upload/graphqlUploadExpress.mjs'","cause":"Using named import instead of default import for the middleware module.","error":"TypeError: graphqlUploadExpress is not a function"},{"fix":"Update to a newer version (>=14) or use the correct extension: 'graphql-upload/GraphQLUpload.js' for older versions.","cause":"The package version is <14.0.0 where modules were in .js files.","error":"Error: Cannot find module 'graphql-upload/GraphQLUpload.mjs'"},{"fix":"Await the file promise first: const { createReadStream } = await file;","cause":"Calling createReadStream on the file promise before awaiting it, or the promise failed.","error":"TypeError: file.createReadStream is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}