{"id":23648255,"url":"https://github.com/quicksend/transmit","last_synced_at":"2025-08-31T23:32:48.894Z","repository":{"id":38963503,"uuid":"348112845","full_name":"quicksend/transmit","owner":"quicksend","description":"An alternative to Multer for handling multipart/form-data","archived":false,"fork":false,"pushed_at":"2024-02-05T01:14:16.000Z","size":13794,"stargazers_count":9,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-23T10:57:46.285Z","etag":null,"topics":["file-upload","form","form-data","formdata","javascript","multipart","nodejs","typescript"],"latest_commit_sha":null,"homepage":"https://quicksend.github.io/transmit","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quicksend.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-15T20:26:42.000Z","updated_at":"2024-02-04T11:11:44.000Z","dependencies_parsed_at":"2023-02-13T19:16:59.163Z","dependency_job_id":null,"html_url":"https://github.com/quicksend/transmit","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/quicksend/transmit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicksend%2Ftransmit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicksend%2Ftransmit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicksend%2Ftransmit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicksend%2Ftransmit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quicksend","download_url":"https://codeload.github.com/quicksend/transmit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quicksend%2Ftransmit/sbom","scorecard":{"id":755867,"data":{"date":"2025-08-11","repo":{"name":"github.com/quicksend/transmit","commit":"071721b7eca85a045a2be376cb990f3425cc6ffc"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/18 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/docs.yml:1","Warn: no topLevel permission defined: .github/workflows/test.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 12 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Pinned-Dependencies","score":3,"reason":"dependency not pinned by hash detected -- score normalized to 3","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/docs.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/docs.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/docs.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/docs.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/test.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/test.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/test.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/test.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/quicksend/transmit/test.yml/master?enable=pin","Info:   0 out of   6 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   3 third-party GitHubAction dependencies pinned","Info:   2 out of   2 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Vulnerabilities","score":0,"reason":"22 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-wm7h-9275-46v2","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-75v8-2h7p-7m2m","Warn: Project is vulnerable to: GHSA-5v2h-r2cx-5xgj","Warn: Project is vulnerable to: GHSA-rrrm-qjm4-v8hf","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-54xq-cgqr-rpm3","Warn: Project is vulnerable to: GHSA-pq67-2wwv-3xjx","Warn: Project is vulnerable to: GHSA-8cj5-5rvv-wf4v","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T21:39:25.670Z","repository_id":38963503,"created_at":"2025-08-22T21:39:25.676Z","updated_at":"2025-08-22T21:39:25.676Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273052721,"owners_count":25037262,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["file-upload","form","form-data","formdata","javascript","multipart","nodejs","typescript"],"created_at":"2024-12-28T14:52:39.564Z","updated_at":"2025-08-31T23:32:47.848Z","avatar_url":"https://github.com/quicksend.png","language":"TypeScript","readme":"# Transmit\n\n[![Build Status](https://github.com/quicksend/transmit/actions/workflows/test.yml/badge.svg)](https://github.com/quicksend/transmit/actions/workflows/test.yml)\n[![Coverage Status](https://coveralls.io/repos/github/quicksend/transmit/badge.svg?branch=master)](https://coveralls.io/github/quicksend/transmit?branch=master)\n\nAn alternative to [Multer](https://github.com/expressjs/multer) for handling multipart/form-data \n\n## Why?\n\n[Multer](https://github.com/expressjs/multer) and many other multipart/form-data parsers don't remove uploaded files if the request is aborted. This can be a problem if a user uploads large files and abruptly aborts the request, leaving the partially uploaded (and potentially large) file on your system. Transmit automatically deletes uploaded files if it detects that the request has been aborted.\n\nIn addition, Transmit offers a modern API, making use of promises. It also allows you to process and transform incoming files with the use of transformer functions.\n\n## Prerequisites\n - [Node.js](https://nodejs.org/en/) \u003e= v12.21.0\n\n## Installation\n\n```bash\n$ npm install @quicksend/transmit\n$ npm install -D @types/busboy\n```\n\n## Usage\n\nBy default, all files are saved within the [os.tmpdir()](https://nodejs.org/api/os.html#os_os_tmpdir) folder. You can change this by specifying the directory in the options of [DiskManager](https://quicksend.github.io/transmit/classes/diskmanager.html).\n\nExample with Express using a custom upload destination:\n```js\nconst { DiskManager, Transmit } = require(\"@quicksend/transmit\");\n\nconst express = require(\"express\");\n\nconst app = express();\n\n// Implement transmit as an express middleware\nconst upload = (options = {}) =\u003e (req, _res, next) =\u003e {\n  return new Transmit(options)\n    .parseAsync(req)\n    .then((results) =\u003e {\n      req.fields = results.fields;\n      req.files = results.files;\n\n      next();\n    })\n    .catch((error) =\u003e next(error));\n};\n\nconst manager = new DiskManager({\n  directory: \"./uploads\"\n});\n\napp.post(\"/upload\", upload({ manager }), (req, res) =\u003e {\n  res.send({\n    fields: req.fields,\n    files: req.files\n  });\n});\n\napp.listen(3000, () =\u003e {\n  console.log(\"Listening on port 3000\");\n});\n```\n\nExample with Node.js http module:\n```js\nconst { Transmit } = require(\"@quicksend/transmit\");\n\nconst http = require(\"http\");\n\nconst server = http.createServer(async (req, res) =\u003e {\n  if (req.url !== \"/upload\" || req.method.toLowerCase() !== \"post\") {\n    res.writeHead(200, { \"Content-Type\": \"application/json\" });\n    res.end(JSON.stringify({ error: \"Not Found.\" }));\n\n    return;\n  }\n\n  try {\n    const results = await new Transmit().parseAsync(req);\n\n    res.writeHead(200, { \"Content-Type\": \"application/json\" });\n    res.end(JSON.stringify(results, null, 2));\n  } catch (error) {\n    res.writeHead(200, { \"Content-Type\": \"application/json\" });\n    res.end(JSON.stringify(error));\n  }\n});\n\nserver.listen(3000, () =\u003e {\n  console.log(\"Listening on port 3000\");\n});\n```\n\n## NestJS\n\nTransmit can be used with NestJS. Install [nestjs-transmit](https://github.com/quicksend/nestjs-transmit) and follow the instructions on the README.\n\n```bash\n$ npm install @quicksend/nestjs-transmit\n```\n\n## Transformers\n\nFiles can be transformed before it is written to the storage medium. A use case would be resizing uploaded images.\n\nA transformer must be a function that returns a readable stream.\n\nTransformers will run sequentially in the order that they were placed.\n\nExample with [sharp](https://github.com/lovell/sharp) as a resize transformer:\n```js\nconst { DiskManager, Transmit } = require(\"@quicksend/transmit\");\n\nconst express = require(\"express\");\nconst sharp = require(\"sharp\");\n\nconst app = express();\n\n// Implement transmit as an express middleware\nconst upload = (options = {}) =\u003e (req, _res, next) =\u003e {\n  return new Transmit(options)\n    .parseAsync(req)\n    .then((results) =\u003e {\n      req.fields = results.fields;\n      req.files = results.files;\n\n      next();\n    })\n    .catch((error) =\u003e next(error));\n};\n\nconst manager = new DiskManager({\n  directory: \"./uploads\"\n});\n\napp.post(\n  \"/upload\",\n  upload({\n    filter: (file) =\u003e /^image/.test(file.mimetype), // ignore any files that are not images\n    manager,\n    transformers: [() =\u003e sharp().resize(128, 128).png()], // resize any incoming image to 128x128 and save it as a png\n  }),\n  (req, res) =\u003e {\n    res.send({\n      fields: req.fields,\n      files: req.files\n    });\n  }\n);\n\napp.listen(3000, () =\u003e {\n  console.log(\"Listening on port 3000\");\n});\n```\n\n## Custom transmit managers\n\nYou can create your own transmit managers. All managers must implement the [TransmitManager](https://quicksend.github.io/transmit/interfaces/transmitmanager.html) interface.\n\n```ts\nimport { IncomingFile, TransmitManager } from \"@quicksend/transmit\";\n\nexport class CustomTransmitManager implements TransmitManager {\n  handleFile(file: IncomingFile): Promise\u003cNodeJS.WritableStream\u003e | NodeJS.WritableStream {}\n  removeFile(file: IncomingFile): Promise\u003cvoid\u003e | void {}\n}\n```\n\n## Documentation\n\nDetailed documentation can be found [here](https://quicksend.github.io/transmit/)\n\nYou can build the documentation by running:\n```bash\n$ npm run docs\n```\n\n## Tests\n\nRun tests using the following commands:\n```bash\n$ npm run test\n$ npm run test:watch # run jest in watch mode during development\n```\n\nGenerate coverage reports by running:\n```bash\n$ npm run coverage\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquicksend%2Ftransmit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquicksend%2Ftransmit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquicksend%2Ftransmit/lists"}