How toSend Node.js ReadStream objects from Remix loaders
If you're creating route in Remix that needs to send a file from you may want to use node:fs
to get the file content from the system and send it, but if you do the following:
import { createReadStream } from "node:fs";
import { resolve } from "node:path";
export async function loader() {
let file = createReadStream(resolve("./package.json"));
return new Response(file, {
headers: {
"Content-Type": "application/json",
},
});
}
You will notice that TS will yell Argument of type 'ReadStream' is not assignable to parameter of type 'BodyInit'
.
This happens because the global Response
object uses the DOM typings which doesn't know about Node.js ReadStream.
We could solve this by casting the type but a simpler and more type-safe way is to add a single line:
import { Response } from "@remix-run/node";
By importing Response
from @remix-run/node
instead of relying on the global we use a Node.js compatible response object that will accept ReadStream
as possible body.