deno run: Execute a Script in CI
deno run executes a script, granting only the permissions you pass on the command line.
In CI you want deno run to be explicit: name the permissions the job needs and pin dependencies so the build is reproducible.
What it does
deno run takes a file path or URL, type-checks and runs it under the sandbox. Nothing touches the network, filesystem, or environment unless you grant it with an --allow flag. Deno 2 still enforces the same default-deny model.
Common usage
deno run --allow-net --allow-read main.ts
deno run --allow-env=API_URL --allow-net=api.example.com main.ts
# pin dependencies in CI
deno run --frozen --cached-only --allow-net main.tsOptions
| Flag | What it does |
|---|---|
| --allow-net[=hosts] | Grant network access, optionally scoped to hosts |
| --allow-read[=paths] | Grant filesystem read, optionally scoped to paths |
| -A / --allow-all | Grant every permission (avoid in CI where possible) |
| --frozen | Fail if the lockfile would change (Deno 2) |
| --cached-only | Do not download; require modules already in DENO_DIR |
| --no-check | Skip type-checking for a faster run |
In CI
Cache DENO_DIR between jobs so deno run does not re-download on every build, and add --frozen so a drifting lockfile fails the job instead of silently updating. Scope permissions (--allow-net=host) rather than using -A so the sandbox still catches surprises.
Common errors in CI
"error: Requires net access to ..., run again with the --allow-net flag" means the script needs a permission you did not grant. "error: The lockfile is out of date" appears under --frozen when deno.lock no longer matches the imports; regenerate it locally and commit. "Module not found" usually means a typo in the entry path or a missing --cached-only cache.