Streaming files with "readableWebStream" #68109
-
Hey folks, I've previously proposed an implementation of file streaming from route handlers, the tricky part being that Node.js "fs" streams are not exactly the same data structure as web platform ReadableStream. @karlhorky has kindly pointed me towards Node.js builtin (but experimental) I've started a demo application but couldn't make it work yet. Code: https://github.com/eric-burel/demo-readableWebStream You just need to clone, install, run and open the home page. It will trigger an API request that should load an image. But I currently hit an error |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
I had a similar situation as yours. In my case, I was using Puppeteer to create a PDF of a HTML page. The import { Readable } from "node:stream";
import type { ReadableStream as NodeReadableStream } from "node:stream/web";
import type { Browser, PDFOptions } from "puppeteer";
import { launch } from "puppeteer";
async function generatePdfFromHtml(
html: string,
): ReturnType<typeof page.createPDFStream> {
const browser = await launchBrowser();
const page = await browser.newPage();
await page.setContent(html);
const reader = await page
.createPDFStream(DEFAULT_PDF_OPTIONS)
.then((stream) => stream.getReader());
return new ReadableStream<Uint8Array>({
start(controller): Promise<void> {
async function pump(): Promise<void> {
const { done, value } = await reader.read();
if (done) {
controller.close();
closeBrowser(browser);
return;
}
controller.enqueue(value);
await pump();
}
return pump();
},
cancel(reason): void {
void reader.cancel(reason);
closeBrowser(browser);
},
});
}
export async function POST(request: Request): Promise<Response> {
// ....
return new Response(await generatePdfFromHtml(html), {
headers: {
"Content-Type": "application/pdf",
},
});
} Hope it helps! |
Beta Was this translation helpful? Give feedback.
-
Apparently this is a bug in Node.js with |
Beta Was this translation helpful? Give feedback.
-
Thanks @karlhorky for the heads up! Slightly related: I now use this use case as a test for AI-based tooling capabilities - since modern features + lesser documented patterns tend to be their weak point. I've recently tried teaching GitHub Copilot to output a proper file streaming route handler, and documented the ride on my technical blog : https://www.ericburel.tech/blog/teaching-nextjs-to-github-copilot |
Beta Was this translation helpful? Give feedback.
Now that PR nodejs/node#55461 has been released in Node.js v23.8.0:
I can confirm that Node.js v23.8.0
FileHandle.readableWebStream()
can be used without configuration to easily create Web Streams, which can then be passed to Route Handlers 🎉