Deno is a modern JavaScript and TypeScript runtime with a genuinely different design: imports come straight from URLs and registries, TypeScript runs with no build step, and — crucially — it's secure by default. That last part is where Deno on Falix gets interesting, because "secure by default" collides with how the free plan works. This guide covers deno.json, imports, and the permission reality head-on.
| At a glance | |
|---|---|
| You need | A Falix server running the Deno application |
| Plan | Free runs permissionless programs; a Deno app that needs network or env access needs premium (see below) |
| Time | Twenty minutes |
| New to the Deno app? | C#, Deno, Dart, Elixir, and Lua on Falix |
What runs on start
The Deno application starts your code with ./deno run <your JS/TS file> — the entry file variable defaults to app.js, and the deno binary is downloaded into your server folder when the application installs. Note what's missing: there's no install step, because Deno doesn't use node_modules.
Imports — no install step
Deno resolves dependencies directly from your source and caches them on first run. Three kinds of specifier:
| Specifier | Example | Use it for |
|---|---|---|
| URL | import { serve } from "https://deno.land/std/http/server.ts" |
Deno-native modules, pinned by URL |
npm: |
import express from "npm:express@4" |
Reusing packages from the npm ecosystem |
jsr: |
import { encodeBase64 } from "jsr:@std/encoding" |
JSR, the modern registry Deno favours |
There's no lockfile to babysit and no npm install to run — the first execution fetches and caches. That's the upside of Deno's model, and it works the same on Falix as anywhere.
deno.json
deno.json (or deno.jsonc) is Deno's config file. It does three useful jobs:
- An import map — give long URLs short names so
import x from "chi"resolves to a pinned version defined once. - Compiler and format/lint options — TypeScript settings,
fmt, andlintrules. - Tasks — named commands you run with
deno task <name>, like npm scripts.
🎯 Good to know: Tasks are great for your local workflow, but the Falix startup runs
./deno run app.js, notdeno task. Making a task your server's startup command means editing the full startup command — which, as below, is premium-only. On any plan, keep your entry logic reachable from the defaultdeno run <file>.
If your project keeps a deno.json, the Packages page can manage its dependencies for you — it runs deno add under the hood and updates the file (see more runtimes).
The permission reality — read this before you build
This is the one thing that will surprise you, and it's verified on the real runtime: *Deno denies network, environment, and file access unless you explicitly grant it with `--allow-flags.** The default startup runsdeno run` with no flags. So:
- A script that reads an environment variable fails (permission denied).
- A script that opens a network port fails (permission denied).
And here's the sting for web apps: reading SERVER_PORT needs --allow-env, and binding a port needs --allow-net. A Deno web server needs both. Adding --allow-net --allow-env to the command means editing the full startup command — which is a premium-only feature.
| What your Deno program does | Needs a permission flag? | Free plan? |
|---|---|---|
| Pure computation, no I/O | No | ✅ Works |
Reads SERVER_PORT / other env vars |
--allow-env |
⚠️ Needs startup edit (premium) |
| Opens a network port / makes requests | --allow-net |
⚠️ Needs startup edit (premium) |
| Reads or writes files | --allow-read / --allow-write |
⚠️ Needs startup edit (premium) |
⚠️ Heads up: Don't get attached to a free-plan Deno web server. Because it must read
SERVER_PORTand bind a port, it needs the flags, and the flags need a startup-command edit that free plans can't make. On free, plan around Deno programs that don't need those permissions — or, if you want a web app on free, choose a runtime whose default startup already grants what a server needs (Node, Bun, Python, and Go all do).
If you have premium
With premium you can edit the startup command on the Settings page. Grant only what your app needs — --allow-net --allow-env for a typical web server — rather than the blanket -A (allow everything), and Deno's security model keeps working for you instead of against you. Then read the port the usual way (Deno.env.get("SERVER_PORT")) and bind 0.0.0.0, per Your first web app.
Everything beyond the Falix-shaped parts is standard Deno — the official documentation at docs.deno.com covers permissions, deno.json, and the registries in full.