Deno on Falix in depth

How Deno's imports and deno.json work, why npm: and jsr: specifiers mean no install step — and the honest, verified truth about Deno's permission model and what it costs on a free plan.

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, and lint rules.
  • 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, not deno 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 default deno 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_PORT and 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.


Next steps

Was this guide helpful?