This implementation has been designed from the ground up to be more aligned with Deno standards. For instance, you can directly reuse code written for deno serve and handlers for Deno.serve, and it also natively supports
deno shebangs, which minimizes the friction required to deploy existing Deno code to Vercel.
It also provides better support for advanced use-cases, such as specifying environment variables, pre-caching assets, or selecting the Deno version to use through pragmas, and the permissions management system is fully supported.
While Deno Deploy is a great platform, Vercel free tier offers more generous limits for serverless applications.
If you are deploying a fully-fledged Deno application (which requires to be constantly running, requires storage or database, writable filesystem, etc.), Deno Deploy is likely a better fit.
If you are deploying a simple Deno application with simple functions and callbacks, then Vercel with this runtime is a great choice. Note that the free tier of Vercel limits the number of serverless function to 12.
Example of a serverless function using dynamic imports.
Since the file system is read-only
once a function is deployed, the deno cache must be set to a writable directory in order for dynamic
imports to work properly. This can be done by setting the environment variable DENO_DIR to /tmp.
Example of a serverless function including additional files through the --include pragma.
Vercel requires files to be explicitly included in the deployment bundle so if your entrypoint
references any local files that are not statically analyzed, you will need to use this pragma
to explicitly include them (glob patterns are supported).
Example of an interactive serverless function that reads a Request.body provided by an end-user
and and plays a game of Rock Paper Scissors against them.
#!/usr/bin/env -S deno runconst text = { rock: "๐ชจ Rock", paper: "๐ Paper", scissors: "โ๏ธ Scissors" }
exportdefault {
asyncfetch(request) {
const { input } = await request.json()
const cpu = ["rock", "paper", "scissors"][Math.floor(Math.random() * 3)]
switch (true) {
case (input === "rock") && (cpu === "scissors"):
case (input === "paper") && (cpu === "rock"):
case (input === "scissors") && (cpu === "paper"):
returnnewResponse(`You chose [${text[input]}], I chose [${text[cpu]}]. You win! ๐`)
case (input === "rock") && (cpu === "paper"):
case (input === "paper") && (cpu === "scissors"):
case (input === "scissors") && (cpu === "rock"):
returnnewResponse(`You chose [${text[input]}], I chose [${text[cpu]}]. I win! ๐ค`)
default:
returnnewResponse(`We both chose [${text[input]}]. It's a tie! ๐ค`)
}
},
} satisfiesDeno.ServeDefaultExport
Runtime options and permissions may be specified using deno shebangs.
#!/usr/bin/env -S deno run --allow-sysexportdefaultasyncfunctionserve() {
returnnewResponse(Deno.osRelease())
}
โ ๏ธ Important
The parser only supports shebangs that use deno run or deno serve.
โน๏ธ Note
The --allow-read permission for the function's source file is always implicitly granted as it is required to load and run the handler. Under the hood, the handler is run within a WebWorker with the provided permissions.
Specific instructions may be provided to the runtime using the //@vercel: pragma (which must be placed at the top of the file or immediately after the shebang).
Option
Alias
Description
Multiple
Dev
Default
Example
--version
-v
Specify the Deno version to use.
Nยน
latest
-v 2.5.6
--env
-e
Specify environment variables to set.
Y
Y
-e FOO=bar
--include
-i
Specify additional modules to pre-cache.
Y
Nยฒ
-i /assets
ยน: Dev server always uses the currently installed Deno version.
ยฒ: Dev server always has access to the filesystem and not a subset of it.