Awesome-omni-skill deno-deploy
Use when deploying Deno apps to production, asking about Deno Deploy, or working with `deno deploy` CLI commands. Covers deployment workflows, environment variables, KV database access, custom domains, the --tunnel flag for local development, and the `deno deploy` command reference.
git clone https://github.com/diegosouzapw/awesome-omni-skill
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/devops/deno-deploy" ~/.claude/skills/diegosouzapw-awesome-omni-skill-deno-deploy && rm -rf "$T"
skills/devops/deno-deploy/SKILL.mdDeno Deploy
This skill provides guidance for deploying applications to Deno Deploy.
Scope Boundaries
This skill applies only to Deno Deploy questions. Follow these rules:
- If the user asks about AWS Lambda, Vercel, Netlify, Google Cloud Run, Docker, Kubernetes, or any other deployment platform, answer using that platform directly. Do not mention Deno Deploy at all — not as an alternative, not as a comparison, not as a suggestion.
- If the user asks about running a local Deno script (not deploying), answer the local question
directly. Do not mention Deno Deploy, deployment, or the
flag.--tunnel - Do not include
commands, Deno KV, or Deno Deploy environment variable configuration in responses about other platforms or local-only scripts.deno deploy - Only discuss Deno Deploy when the user explicitly asks about Deno Deploy or deploying a Deno application to production.
Important: Use deno deploy
, NOT deployctl
deno deploydeployctlAlways use the
command. Do NOT use deno deploy
deployctl.
is for Deno Deploy Classic (deprecated)deployctl
is the modern, integrated command built into the Deno CLIdeno deploy- Requires Deno >= 2.4.2 - the
subcommand was introduced in Deno 2.4deno deploy
When Unsure About CLI Flags
Always run
before guessing at flags. The --help
deno deploy subcommand has many flags, and
they change between versions. When you're unsure what a command accepts:
# See all subcommands deno deploy --help # See flags for a specific subcommand deno deploy create --help deno deploy env --help deno deploy database --help
This takes seconds and prevents repeated trial-and-error failures. Never assume a flag exists — check first.
Deployment Workflow
Always show the core deploy command first — then explain diagnostic steps. When a user asks "how do I deploy?", lead with the actual command (
deno deploy --prod) before covering pre-flight checks
and configuration.
Step 1: Locate the App Directory
Before running any deploy commands, find where the Deno app is located:
# Check if deno.json exists in current directory if [ -f "deno.json" ] || [ -f "deno.jsonc" ]; then echo "APP_DIR: $(pwd)" else # Look for deno.json in immediate subdirectories find . -maxdepth 2 -name "deno.json" -o -name "deno.jsonc" 2>/dev/null | head -5 fi
All deploy commands must run from the app directory.
Step 2: Pre-Flight Checks
Check Deno version and existing configuration:
# Check Deno version (must be >= 2.4.2) deno --version | head -1 # Check for existing deploy config grep -E '"org"|"app"' deno.json deno.jsonc 2>/dev/null || echo "NO_DEPLOY_CONFIG"
Step 3: Check for Startup Dependencies
Before deploying, check if the app connects to a database or external service at startup (e.g., top-level
await initDb() in main.ts). If it does, the deploy will fail during warmup because the
database doesn't exist yet.
If the app has startup database dependencies, follow this order:
-
Create the app with
so a warmup failure doesn't block you:--no-waitdeno deploy create \ --org <ORG_NAME> --app <APP_NAME> \ --source local --runtime-mode dynamic --entrypoint main.ts \ --build-timeout 5 --build-memory-limit 1024 --region us \ --no-wait -
Provision and assign the database:
deno deploy database provision my-db --kind prisma --region us-east-1 deno deploy database assign my-db --app <APP_NAME> -
Redeploy (now the database exists, warmup will succeed):
deno deploy --prod
If the app has no startup dependencies, skip this step and deploy normally below.
Step 4: Deploy Based on Configuration
If
AND deploy.org
exist in deno.json:deploy.app
# Build if needed (Fresh, Astro, etc.) deno task build # Deploy to production deno deploy --prod
If NO deploy config exists:
Apps must be created before they can be deployed to. You cannot run
deno deploy --prod until
an app exists.
IMPORTANT: Ask the user first - Do they have an existing app on Deno Deploy, or do they need to create a new one?
If they have an existing app, add the config directly to deno.json:
{ "deploy": { "org": "<ORG_NAME>", "app": "<APP_NAME>" } }
The org name is in the Deno Deploy console URL (e.g.,
console.deno.com/your-org-name). Once this
config is in place, subsequent deploys just need deno deploy --prod.
If they need to create a new app:
The CLI needs an organization name. Find it at https://console.deno.com - the org is in the URL path (e.g.,
console.deno.com/your-org-name).
Interactive creation (opens a browser — only works when a human is at the keyboard):
deno deploy create --org <ORG_NAME> # A browser window opens - complete the app creation there
Non-interactive creation (use when an AI agent is performing the deploy, or in CI/CD):
deno deploy create \ --org <ORG_NAME> \ --app <APP_NAME> \ --source local \ --runtime-mode dynamic \ --entrypoint main.ts \ --build-timeout 5 \ --build-memory-limit 1024 \ --region us
The create command also does the initial deploy. After it completes,
deno.json is updated with
deploy.org and deploy.app automatically. From that point on, subsequent deploys only need:
deno deploy --prod
After completion, verify the config was saved:
grep -E '"org"|"app"' deno.json
When an AI agent is performing the deployment, always use the non-interactive flow with explicit flags. The interactive flow requires browser windows and terminal prompts that agents cannot navigate.
Core Commands
Production Deployment
deno deploy --prod
Preview Deployment
deno deploy
Preview deployments create a unique URL for testing without affecting production.
Targeting Specific Apps
deno deploy --org my-org --app my-app --prod
Configuring an Entrypoint
Set the entrypoint in your
deno.json (this is used by deno deploy create during app creation):
{ "deploy": { "entrypoint": "main.ts" } }
Note:
--entrypoint is a flag on deno deploy create, not on deno deploy itself.
Additional Flags
These flags are available on
deno deploy create (and apply during the initial deploy):
| Flag | Purpose |
|---|---|
| Include node_modules directory in upload |
| Skip waiting for the build to complete |
Creating Apps (Non-Interactive Reference)
When any flag beyond
--org is provided, deno deploy create runs in non-interactive mode — all
required flags must be specified. This is the recommended approach for AI agents and CI/CD
pipelines.
Required Flags
| Flag | Description |
|---|---|
| Organization name |
| Application name (becomes your URL: ) |
| Deploy from local files or a GitHub repo |
| Build timeout: 5, 10, 15, 20, 25, or 30 |
| Memory limit: 1024, 2048, 3072, or 4096 |
| Deployment region: us, eu, or global |
GitHub Source Flags
When using
--source github, you also need:
| Flag | Description |
|---|---|
| GitHub repository owner |
| GitHub repository name |
Build Configuration Flags
| Flag | Description |
|---|---|
| Path to app directory (for monorepos) |
| Framework preset (see Frameworks) |
| Custom install command |
| Custom build command |
| Command to run before deploy |
| Skip auto-detection of framework config |
The CLI auto-detects your framework and build configuration. If a framework is detected, you can skip
--install-command, --build-command, --pre-deploy-command, and --runtime-mode — they'll
be inferred from the preset. Use --do-not-use-detected-build-config to override detection. When
using this flag, all three build commands (--install-command, --build-command,
--pre-deploy-command) plus --runtime-mode become required — omitting any of them causes exit
code 2.
Runtime Mode Flags
You must pick a runtime mode with
--runtime-mode <dynamic|static> (unless a framework preset
handles it).
Dynamic mode (for apps with a server):
| Flag | Description |
|---|---|
| Entry file (required for dynamic mode) |
| Arguments passed to entrypoint (repeatable) |
| Working directory for the process |
Static mode (for static sites):
| Flag | Description |
|---|---|
| Directory to serve static files from (required) |
| Serve index.html for routes that don't match a file |
Other Flags
| Flag | Description |
|---|---|
| Validate everything without actually creating the app |
| Don't wait for the build to complete |
| Include node_modules in the upload |
Examples
Simple Deno server:
deno deploy create \ --org my-org --app my-api \ --source local \ --runtime-mode dynamic --entrypoint main.ts \ --build-timeout 5 --build-memory-limit 1024 --region us
Fresh app (framework auto-detected):
deno deploy create \ --org my-org --app my-fresh-app \ --source local \ --build-timeout 5 --build-memory-limit 1024 --region us
Next.js from GitHub:
deno deploy create \ --org my-org --app my-next-app \ --source github --owner my-github-user --repo my-next-repo \ --framework-preset Next \ --build-timeout 15 --build-memory-limit 2048 --region us \ --allow-node-modules
Static site:
deno deploy create \ --org my-org --app my-static-site \ --source local \ --runtime-mode static --static-dir dist --single-page-app \ --build-command "deno task build" \ --build-timeout 5 --build-memory-limit 1024 --region us
Environment Variables
Contexts
Deno Deploy has three "contexts" - logical environments where your code runs, each with its own set of variables:
| Context | Purpose |
|---|---|
| Production | Live traffic on your production URL |
| Development | Preview deployments and branch URLs |
| Build | Only available during the build process |
You can set different values for the same variable in each context. For example, you might use a test database URL in Development and the real one in Production.
Predefined Variables
These are automatically available in your code:
| Variable | Description |
|---|---|
| Always when running on Deno Deploy |
| Unique ID for the current deployment |
| Your organization's ID |
| Your application's ID |
| Set to during builds only |
Accessing Variables in Code
const dbUrl = Deno.env.get("DATABASE_URL") const isDenoDeploy = Deno.env.get("DENO_DEPLOY") === "1"
Managing Variables via CLI
# Add a plain text variable deno deploy env add DATABASE_URL "postgres://..." # Add a secret variable (hidden after creation, only readable in code) deno deploy env add API_KEY "sk-..." --secret # List all variables deno deploy env list # Update just the value (keeps contexts and secret status) deno deploy env update-value DATABASE_URL "postgres://new-url..." # Update which contexts a variable applies to deno deploy env update-contexts DATABASE_URL production development # Delete a variable deno deploy env delete DATABASE_URL # Load from .env file (all values treated as secrets by default) deno deploy env load .env.production # Load from .env file, marking specific keys as non-secrets deno deploy env load .env.production --non-secrets PUBLIC_URL APP_NAME
Variable Types
- Plain text - Visible in the dashboard, good for feature flags and non-sensitive config
- Secrets - Hidden after creation, only readable in your code, use for API keys and credentials
Limits
- Key names: max 128 bytes
- Values: max 16 KB
- Keys cannot start with
,DENO_
, orLD_OTEL_
Viewing Logs
# Stream live logs deno deploy logs # Filter by date range deno deploy logs --start 2026-01-15 --end 2026-01-16
Databases & Storage
Deno Deploy provides built-in database support with automatic environment isolation. Each environment (production, preview, branch) gets its own isolated database automatically.
Available Options
| Engine | Use Case |
|---|---|
| Deno KV | Key-value storage, simple data, counters, sessions |
| PostgreSQL | Relational data, complex queries, existing Postgres apps |
Deno KV Quick Start
No configuration needed - just use the built-in API:
const kv = await Deno.openKv() // Store data await kv.set(["users", "alice"], { name: "Alice", role: "admin" }) // Retrieve data const user = await kv.get(["users", "alice"]) console.log(user.value) // { name: "Alice", role: "admin" } // List by prefix for await (const entry of kv.list({ prefix: ["users"] })) { console.log(entry.key, entry.value) }
Deno Deploy automatically connects to the correct database based on your environment.
PostgreSQL
For PostgreSQL, Deno Deploy injects environment variables (
DATABASE_URL, PGHOST, etc.) that most
libraries detect automatically:
// Recommended: npm:pg (best PostgreSQL driver for Deno Deploy) import pg from "npm:pg" const pool = new pg.Pool() // Reads DATABASE_URL from environment automatically
Provisioning
Use the
deno deploy database command to provision and manage databases:
# Provision a Deno KV database deno deploy database provision my-database --kind denokv # Provision a Prisma PostgreSQL database deno deploy database provision my-database --kind prisma --region us-east-1 # Assign to your app deno deploy database assign my-database --app my-app
For detailed CLI commands, see Databases.
Local Development
Use
--tunnel to connect to your hosted development database locally:
deno task --tunnel dev
See Databases and Deno KV for detailed documentation.
Local Development Tunnel
The tunnel feature lets you expose your local development server to the internet. This is useful for:
- Testing webhooks - Receive webhook callbacks from external services
- Sharing with teammates - Let others preview your local work
- Mobile testing - Access your local server from other devices
Basic Usage
Add the
--tunnel flag when running your app:
deno run --tunnel -A main.ts
The first time you run this, it will:
- Ask you to authenticate with Deno Deploy (opens a browser)
- Ask you to select which app to connect the tunnel to
- Generate a public URL that forwards requests to your local server
Using with Tasks
You can use
--tunnel with your existing tasks in deno.json:
deno task --tunnel dev
This runs your
dev task with the tunnel enabled.
What the Tunnel Provides
Beyond just forwarding requests, the tunnel also:
- Syncs environment variables - Variables set in your Deno Deploy app's "Local" context become available to your local process
- Sends logs and metrics - OpenTelemetry data goes to the Deno Deploy dashboard (filter with
)context:local - Connects to databases - Automatically connects to your assigned local development databases
Managing Tunnels
- View active tunnels in the Deno Deploy dashboard under the "Tunnels" tab
- Stop a tunnel by terminating the Deno process (Ctrl+C)
Command Reference
| Command | Purpose |
|---|---|
| Deploy to production (app must exist first) |
| Preview deployment |
| Create new app (interactive) |
| Create new app (non-interactive, see full flags above) |
| Create app without waiting for build to complete |
| Create app including node_modules |
| Add plain text environment variable |
| Add secret environment variable |
| List environment variables |
| Update variable value (keeps contexts/secret status) |
| Update which contexts a variable applies to |
| Delete environment variable |
| Load variables from .env file (defaults to secret) |
| Load .env file, marking specific keys as non-secrets |
| Provision a new database |
| Assign database to an app |
| View deployment logs |
| Start local tunnel |
| Run task with tunnel |
Edge Runtime Notes
Deno Deploy runs in one or many regions (globally distributed). Keep in mind:
- Environment variables - Must be set via
, not .env files at runtimedeno deploy env - Global distribution - Code runs at the region closest to users
- Cold starts - First request after idle may be slightly slower
Additional References
- Authentication - Interactive and CI/CD authentication
- Databases - Database provisioning and connections
- Deno KV - Key-value storage API and examples
- Domains - Custom domains and SSL certificates
- Frameworks - Framework-specific deployment guides
- Organizations - Managing orgs and members
- Runtime - Lifecycle, cold starts, and limitations
- Troubleshooting - Common issues and solutions
Documentation
- Official docs: https://docs.deno.com/deploy/
- CLI reference: https://docs.deno.com/runtime/reference/cli/deploy/
- Databases: https://docs.deno.com/deploy/reference/databases/
- Deno KV: https://docs.deno.com/deploy/reference/deno_kv/
- Domains: https://docs.deno.com/deploy/reference/domains/
- Environment variables & contexts: https://docs.deno.com/deploy/reference/env_vars_and_contexts/
- Organizations: https://docs.deno.com/deploy/reference/organizations/
- Runtime: https://docs.deno.com/deploy/reference/runtime/
- Tunnel: https://docs.deno.com/deploy/reference/tunnel/