Runtime
Bundler
Package Manager
Test Runner
Guides
Reference
Blog
Install Bun
Guides HTTP & Networking

Upload files via HTTP using FormData

To upload files over HTTP with Bun, use the FormData API. Start with an HTTP server that serves an HTML form.

index.ts
const server = Bun.serve({
  port: 4000,
  async fetch(req) {
    const url = new URL(req.url);

    // return index.html for root path
    if (url.pathname === "/")
      return new Response(Bun.file("index.html"), {
        headers: {
          "Content-Type": "text/html",
        },
      });

    return new Response("Not Found", { status: 404 });
  },
});

console.log(`Listening on http://localhost:${server.port}`);

Define the HTML form in another file, index.html.

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Form</title>
  </head>
  <body>
    <form action="/action" method="post" enctype="multipart/form-data">
      <input type="text" name="name" placeholder="Name" />
      <input type="file" name="profilePicture" />
      <input type="submit" value="Submit" />
    </form>
  </body>
</html>

Run the server and visit localhost:4000 to see the form.

$ bun run index.ts
Listening on http://localhost:4000

The form sends a POST request with the form data to the /action endpoint. Handle that request in the server.

First, call .formData() on the incoming Request to asynchronously parse its contents into a FormData instance. Then use .get() to extract the name and profilePicture fields; name is a string and profilePicture is a Blob.

Finally, write the Blob to disk with Bun.write().

index.ts
const server = Bun.serve({
  port: 4000,
  async fetch(req) {
    const url = new URL(req.url);

    // return index.html for root path
    if (url.pathname === "/")
      return new Response(Bun.file("index.html"), {
        headers: {
          "Content-Type": "text/html",
        },
      });

    // parse formdata at /action
    if (url.pathname === "/action") { 
      const formdata = await req.formData(); 
      const name = formdata.get("name"); 
      const profilePicture = formdata.get("profilePicture"); 
      if (!profilePicture) throw new Error("Must upload a profile picture."); 
      // write profilePicture to disk
      await Bun.write("profilePicture.png", profilePicture); 
      return new Response("Success"); 
    } 

    return new Response("Not Found", { status: 404 });
  },
});

On this page

No Headings