Complete streaming example
index.ts
import { Volt } from 'voltts';
const app = new Volt();
app.get('/events', () => {
const encoder = new TextEncoder();
const stream = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(encoder.encode('event: greeting\ndata: {"message":"Hello Volt"}\n\n'));
controller.close();
},
});
return new Response(stream, {
headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache' },
});
});
app.get('/download', () => new Response('id,title\n1,Coffee\n', {
headers: {
'Content-Type': 'text/csv; charset=utf-8',
'Content-Disposition': 'attachment; filename="products.csv"',
},
}));
if (globalThis._importMeta_.main) app.listen(3000);
export default app;Try both responses
bash
bun run index.ts
curl -N http://localhost:3000/events
curl -i http://localhost:3000/downloadThe event endpoint emits one greeting event and closes; it is not a long-running subscription. The download endpoint returns a small generated CSV with a download filename.
Extending the stream
For a continuous stream, release timers or subscriptions in cancel() and handle client disconnects. Return a native Response to control headers and status. Set the appropriate content type when returning a bare ReadableStream through the stream() helper. The Node adapter forwards response chunks but has different backpressure and runtime behavior from Bun's server.