Streaming
Overview​
docxio supports streaming .docx bytes as a ReadableStream, which is useful for HTTP responses where you want to start sending data before the entire document is assembled.
renderToStream​
import { renderToStream } from "docxio";
const stream = renderToStream(
<document title="Streamed Report">
<section>
<paragraph><run>Hello from a stream!</run></paragraph>
</section>
</document>
);
The returned stream is a standard web ReadableStream<Uint8Array>.
HTTP response (Bun)​
import { renderToStream } from "docxio";
Bun.serve({
fetch(req) {
const doc = (
<document title="Report">
<section>
<paragraph><run>Generated on the fly.</run></paragraph>
</section>
</document>
);
const stream = renderToStream(doc);
return new Response(stream, {
headers: {
"Content-Type":
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"Content-Disposition": 'attachment; filename="report.docx"',
},
});
},
});
HTTP response (Node.js / Express)​
import { renderToReadableStream } from "docxio";
import { Readable } from "node:stream";
app.get("/report.docx", async (req, res) => {
const doc = (
<document title="Report">
<section>
<paragraph><run>Server-generated document.</run></paragraph>
</section>
</document>
);
const webStream = renderToReadableStream(doc);
const nodeStream = Readable.fromWeb(webStream);
res.setHeader(
"Content-Type",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
);
res.setHeader("Content-Disposition", 'attachment; filename="report.docx"');
nodeStream.pipe(res);
});
When to use streaming​
Streaming is beneficial when:
- The document is large and you want to reduce time-to-first-byte
- You are serving documents over HTTP and want to avoid buffering the entire file in memory
- You are piping directly to a file or another stream consumer
For small documents or when you need the complete bytes (e.g., to calculate a hash), use render() instead.