Skip to main content

Building Serverless Functions with Deno


Why Deno?

You can be productive immediately with Deno when you start building your serverless function:

Serverless functions

Building a serverless function with Deno is as simple as creating a web server that accepts a request and returns a response:

Deno.serve((req) => new Response("Hello world"));

Learn more about Deno.serve() in our manual.

Here’s a more advanced example of a serverless function that resizes an image given a set of querystring parameters:

import {
  ImageMagick,
  initializeImageMagick,
  MagickGeometry,
} from "https://deno.land/x/imagemagick_deno@0.0.14/mod.ts";
import { parseMediaType } from "https://deno.land/std@0.175.0/media_types/parse_media_type.ts";

await initializeImageMagick();

function parseParams(reqUrl: URL) {
  const image = reqUrl.searchParams.get("image");
  if (image == null) {
    return "Missing 'image' query parameter.";
  }
  const height = Number(reqUrl.searchParams.get("height")) || 0;
  const width = Number(reqUrl.searchParams.get("width")) || 0;
  if (height === 0 && width === 0) {
    return "Missing non-zero 'height' or 'width' query parameter.";
  }
  if (height < 0 || width < 0) {
    return "Negative height or width is not supported.";
  }
  const maxDimension = 2048;
  if (height > maxDimension || width > maxDimension) {
    return `Width and height cannot exceed ${maxDimension}.`;
  }
  const mode = reqUrl.searchParams.get("mode") || "resize";
  if (mode !== "resize" && mode !== "crop") {
    return "Mode not accepted: please use 'resize' or 'crop'.";
  }
  return {
    image,
    height,
    width,
    mode,
  };
}

async function getRemoteImage(image: string) {
  const sourceRes = await fetch(image);
  if (!sourceRes.ok) {
    return "Error retrieving image from URL.";
  }
  const mediaType = parseMediaType(sourceRes.headers.get("Content-Type")!)[0];
  if (mediaType.split("/")[0] !== "image") {
    return "URL is not image type.";
  }
  return {
    buffer: new Uint8Array(await sourceRes.arrayBuffer()),
    mediaType,
  };
}

function modifyImage(
  imageBuffer: Uint8Array,
  params: { width: number; height: number; mode: "resize" | "crop" },
) {
  const sizingData = new MagickGeometry(
    params.width,
    params.height,
  );
  sizingData.ignoreAspectRatio = params.height > 0 && params.width > 0;
  return new Promise<Uint8Array>((resolve) => {
    ImageMagick.read(imageBuffer, (image) => {
      if (params.mode === "resize") {
        image.resize(sizingData);
      } else {
        image.crop(sizingData);
      }
      image.write((data) => resolve(data));
    });
  });
}

Deno.serve(
  async (req: Request) => {
    const reqURL = new URL(req.url);
    const params = parseParams(reqURL);
    if (typeof params === "string") {
      return new Response(params, { status: 400 });
    }
    const remoteImage = await getRemoteImage(params.image);
    if (remoteImage === "string") {
      return new Response(remoteImage, { status: 400 });
    }
    const modifiedImage = await modifyImage(remoteImage.buffer, params);
    return new Response(modifiedImage, {
      headers: {
        "Content-Type": remoteImage.mediaType,
      },
    });
  },
);

View the source, try the demo, or read the accompanying blog post.

More complex serverless functions can:

  • Access browser API such as geolocation
  • Personalize user experience by overwriting HTTP content
  • Handle user authentication and session requests
  • Resize images
  • Generate OG and meta images on the fly
  • Handle requests for Discord or Slack bots

and much more.

Add State with Deno KV

Deno KV, a globally replicated database, is the easiest way to add state to your server. You don’t need to copy or paste environmental variables or have a separate step to provision a database. All you need is one line of code:

const kv = await Deno.openKv();

You can add state to your serverless functions so that they can store user information across sessions, unlocking a whole new set of use cases and functionalities.

What about Node?
In Node.js, before you can add state to your function, you would need to sign up for a cloud database provider, setup a new database, grab the necessary API keys and unique address and set them as environmental variables.

Deploying your serverless function to Deno Deploy

Deno Deploy, our serverless edge platform, allows you to host and run your functions at the edge close to your users. Your serverless function will have high availability and minimal network latencies.

Hosting your function on Deno Deploy is simple and free by connecting a GitHub account.

Learn why the edge is the future of web.

You can also deploy your Deno serverless functions to Cloudflare.

Additional Resources

Here are some examples, blog posts, and videos about building serverless functions with Deno.