This file is here for legacy reasons, for anyone who wants to use Deno Deploy or old ways we used to do things. The recommended setup instead now is to use Bun, with our own shared server used for hosting.
Client-side only website? Free Deno Deploy is all you need!
Using Deno Deploy is (currently) free, and allows you to be in control of the hosting environment without even needing to provide credit card details. If you know you just have a static website with no server-side functionality, then it's perfectly fine to use it.
Make a deno.js with:
import { serveDir } from 'jsr:@std/http/file-server'
Deno.serve(req => serveDir(req, { fsRoot: './public' }))
... to serve all files in ./public.
deno.jsNote that if your website has a build step, you'll need to build it first with eg bun build ./index.html --outdir=dist
Hono is a lightweight web framework that works in Bun, Deno and Node. It has good progression from a simple static client-side website up to full server-side functionality. Here's some sample usage:
import { Hono } from 'hono'
import { serveStatic } from 'hono/bun'
let app = new Hono()
// various route handlers here...
app.get('/now', (c) => c.text(Date.now()))
app.use('/*', serveStatic({ root: './web' }))
app.get('*', serveStatic({ path: './web/404.html'}))
app.post('/email', (c) => {
// ...
return c.text('ok')
})
// run the server
let server = Bun.serve({ fetch: app.fetch })
console.log(`Hono server started at ${server.url}`)
Heroku allows server-side Bun at a small cost.
Heroku provides a cheap way for you to run your Bun project with server-side processing. But you'll need to provide your credit card details and pay ~ยฃ5/month. Also note that Heroku 'dynos' are ephemeral - they get destroyed and created every 24h, so files (like local SQLite databases) won't persist longer than a day maximum.
Begin by creating a file called Procfile with a single line inside:
web: NODE_ENV=production bun server.js
Commit and push this change.
Create an account on Heroku and set up a new project. You'll need to add a buildpack to run Bun within your project settings. Here's the URL you need for the buildpack: https://github.com/jakeg/heroku-buildpack-bun (yes, I made the buildpack!)
Running in production with Bun on Heroku doesn't require a build step.
Locally, you'll still be running bun server.js to run your app. In production on Heroku, it runs the same command but with an environment variable called NODE_ENV set to production (via the contents of your Procfile). When run this way (in 'production mode'), HMR and detailed error messages are turned off, and a few other things.
You can run in production mode locally with NODE_ENV=production bun server.js (just as Heroku does via the Procfile). Usually you just want to run bun server.js on your computer, but if there's a problem with production, this can be a good way to test things out.
Koyeb allows server-side Bun for free, but with some limits and disadvantages.
This guide takes you through how to Deploy a Bun website via Koyeb.
Advantages vs Deno Deploy:
Disadvantages vs Deno Deploy:
Koyeb uses something called Docker to run Bun apps. For this to work, you'll need to make a file in the root of your repo called Dockerfile (no file extension):
FROM oven/bun:1
WORKDIR /app
COPY . .
ARG PORT
EXPOSE ${PORT:-3000}
CMD ["bun", "server.js"]
... note that if you called your file eg server-bun.js instead of server.js then you should change the bottom line of the Dockerfile to match.
Save, commit and push the Dockerfile to your repo.
You can run code once at build-time when you deploy a new version of your app by adding a RUN line to your Dockerfile. Say we want to run bun reset.js on every deploy, we'd change our Dockerfile to:
FROM oven/bun:1
WORKDIR /app
COPY . .
RUN bun reset.js
ARG PORT
EXPOSE ${PORT:-3000}
CMD ["bun", "server.js"]
Go to Koyeb and 'Sign up', choosign to 'Sign up with GitHub'. Once signed up, choose 'Bun' under 'Deploy one-click app'. Under 'Source' select your repo. Leave other options unchanged.
Click 'Deploy'. Assuming no errors, your app should be live in ~2mins.
By default it will have given your app a horrible web address. Fix this by going to the 'Overview' then clicking the ... next to the service and selecting 'Edit app'. Under 'Koyeb subdomain' put in a better/shorter address.
This assumes you have a PostgreSQL database setup already, eg with Supabase.
If you don't yet have Deno installed (check by running deno -v), install it with:
curl -fsSL https://deno.land/install.sh | sh
Create a file name simply .env in the current folder with a single line in it (ensuring to use your connection string):
DB_CONN="postgresql://...YOUR_CONNECTION_STRING_HERE..."
Create a file, say first.js:
import * as postgres from "https://deno.land/x/postgres@v0.19.3/mod.ts"
let db = new postgres.Client(Deno.env.get('DB_CONN'))
db.query = db.queryObject // handy alias
let x = await db.query`SELECT 1`
console.table(x.rows)
Run it with:
deno run -A --env-file first.js
... note the additional --env-file which loads the .env file.
You could combine this with a web server like so:
import * as postgres from "https://deno.land/x/postgres@v0.19.3/mod.ts"
let db = new postgres.Client(Deno.env.get('DB_CONN'))
db.query = db.queryObject // handy alias
Deno.serve(async (req) => {
let res = await db.query`SELECT 1`
return new Response(JSON.stringify(res.rows))
})