Elysia
Mount the Files gateway in an Elysia app. Web-native on Bun - forward the raw Request with parse:'none' so the gateway reads the body itself.
Elysia is Web-native (it runs on Bun), so the handler context carries the raw request and the gateway consumes it directly — ({ request }) => router.handle(request). Register it with all so all three methods reach the gateway: it dispatches on the method internally (GET = download, POST = the JSON verbs, PUT = upload).
import { Elysia } from "elysia";
import { createFiles } from "files-sdk";
import { s3 } from "files-sdk/s3";
import { createFilesRouter } from "files-sdk/api";
const router = createFilesRouter({
files: createFiles({ adapter: s3({ bucket: "uploads" }) }),
allowedOrigins: ["https://app.example.com"],
authorize: async ({ req }) => {
/* throw to deny, or return a per-user constraint — see /ui/server/authorization */
},
});
const app = new Elysia()
// `parse: "none"` keeps Elysia from consuming the body the gateway must read.
.all("/api/files", ({ request }) => router.handle(request), { parse: "none" })
.listen(3000);Elysia eagerly parses the request body before your handler runs, and a Web
Request body can only be read once — so without parse: "none" the gateway
sees an already-consumed stream ("body already used"). This affects the JSON
verbs and the proxy/explicit-key PUT upload, both of which read the raw
body.
See the gateway options for the full configuration and the authorize model for locking it down.
Deno
Serve the Files gateway from Deno.serve. The gateway is a Web fetch handler, so it drops in with no adapter - import the SDK with the npm specifier.
Express
Mount the Files gateway on a Node server. Bridges IncomingMessage/ServerResponse to the Web Request/Response the gateway speaks - also works with Connect and a raw http server.