# How to Deploy Applications Using Deno Deploy: CLI Workflow and Edge Runtime

> Deploy applications with Deno Deploy using the CLI workflow and edge runtime. Learn how to run JavaScript and TypeScript globally with V8 isolates via the "deno deploy" command.

- Repository: [Deno/deno](https://github.com/denoland/deno)
- Tags: how-to-guide
- Published: 2026-02-26

---

**Deno Deploy is a serverless edge platform that runs JavaScript and TypeScript code at global CDN locations using V8 isolates, deployed directly from the Deno CLI via the `deno deploy` command.**

Deno Deploy enables zero-configuration serverless hosting for Deno applications at the network edge. According to the denoland/deno repository, the deployment workflow is orchestrated by the `deno deploy` subcommand implemented in [`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs), which bundles your source code and communicates with the Deploy API. This workflow supports immutable versioning, automatic scaling, and native TypeScript execution without build steps.

## Project Structure and Requirements

A **deployable project** must contain a single entry point (e.g., [`main.ts`](https://github.com/denoland/deno/blob/main/main.ts)) compatible with the Deno runtime. Before uploading, the CLI validates that the entry file exists and checks for **import maps** and required permissions.

The entry module must use Deno-compatible APIs and standard Web platform features. For example, a minimal HTTP server uses the standard library:

```typescript
// main.ts
import { serve } from "https://deno.land/std@0.221.0/http/server.ts";

serve((_req) => new Response("Hello from Deno Deploy!"));

```

## The Deployment Pipeline

The `deno deploy` command executes a six-step pipeline defined in [`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs):

1. **Project Validation** – Verifies the entry file exists, checks permissions, and resolves import maps.
2. **Bundling** – Packages all imported modules into a single JavaScript file using Deno's bundler.
3. **Auth Token Retrieval** – Reads the **Deno Deploy token** from `~/.deno/deploy.key` or prompts for login.
4. **Upload** – Transmits the bundle to the Deploy API endpoint `/v1/projects/:id/deployments`.
5. **Response Handling** – Returns the deployment URL (e.g., `https://<project>.deno.dev`) and optionally watches for updates.
6. **Server-Side Activation** – The service stores the artifact and provisions V8 isolates for incoming requests.

### Authenticating the CLI

Before your first deployment, authenticate your machine:

```bash
deno deploy login

```

This command stores your access token in `~/.deno/deploy.key` for subsequent CLI operations.

### Deploying Your Application

Execute the deploy command with your entry file path:

```bash
deno deploy main.ts

```

The CLI resolves dependencies, creates the bundle, and uploads the artifact to the Deno Deploy infrastructure.

## Source Code Architecture

The deployment system spans two critical modules in the Deno repository:

**[`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs)** implements the high-level `deno deploy` subcommand. This module handles argument parsing, project validation, dependency bundling, authentication management, and HTTPS communication with the Deploy API.

**[`cli/ops/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/ops/deploy.rs)** provides low-level operations bridging the CLI and core runtime. This file manages authentication state, project creation, and artifact upload mechanisms through internal op functions that interface with the TypeScript runtime.

## Edge Runtime Execution Model

Once uploaded, your application executes on Deno Deploy's **edge runtime**, which provides specific architectural characteristics:

**V8 Isolates** – Each request runs in a lightweight V8 isolate initialized from your bundled code. The platform routes traffic to the nearest global edge location to minimize latency.

**Zero-Configuration Scaling** – The service automatically scales isolate instances based on request volume without manual server or container management.

**Immutable Deployments** – Every upload creates a new, versioned deployment with a unique URL. You can instantly roll back traffic to previous versions using their specific deployment URLs.

**Native Deno Compatibility** – The edge runtime uses the same engine as the Deno CLI, ensuring support for TypeScript, top-level `await`, and the Deno permissions model enforced at deployment time.

## Continuous Integration Setup

For automated deployments, integrate the `deployctl` utility into CI pipelines. The following GitHub Actions workflow deploys on every push to the main branch:

```yaml

# .github/workflows/deploy.yml

name: Deploy to Deno Deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: denoland/setup-deno@v1
      - run: deno install -A --quiet https://deno.land/x/deploy/deployctl.ts
      - env:
          DENO_DEPLOY_TOKEN: ${{ secrets.DENO_DEPLOY_TOKEN }}
        run: deno run -A https://deno.land/x/deploy/deployctl.ts deploy --project=my-project main.ts

```

This configuration installs the Deno CLI, authenticates using a repository secret, and triggers deployment via the Deploy API.

## Summary

- **Deno Deploy** provides serverless edge hosting for Deno applications using V8 isolates distributed across a global CDN.
- The **`deno deploy`** command in [`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs) bundles your code and uploads it to `/v1/projects/:id/deployments` after validating structure and reading auth tokens from `~/.deno/deploy.key`.
- Each deployment creates an **immutable version** that runs in automatically scaled isolates at edge locations nearest to your users.
- Applications must use Deno-compatible APIs and can leverage native TypeScript support without transpilation.
- **CI/CD integration** uses `deployctl` with the `DENO_DEPLOY_TOKEN` environment variable for automated, headless deployments.

## Frequently Asked Questions

### What is the difference between `deno deploy` and `deployctl`?

**`deno deploy`** is the native CLI subcommand implemented in [`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs) that handles bundling, authentication, and deployment directly from the Deno binary. **`deployctl`** is a standalone TypeScript utility ([`x/deploy/deployctl.ts`](https://github.com/denoland/deno/blob/main/x/deploy/deployctl.ts)) designed for CI/CD pipelines that wraps the same Deploy API but provides additional project management flags. Both ultimately transmit bundles to the `/v1/projects/:id/deployments` endpoint.

### How does Deno Deploy handle environment variables?

Environment variables are configured through the Deno Deploy dashboard or API, never committed to source code. During execution, the runtime injects these values into the Deno process, accessible via `Deno.env.get()`. The [`cli/ops/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/ops/deploy.rs) module manages the secure association of these variables with your deployment artifacts.

### Can I use npm modules with Deno Deploy?

Yes, Deno Deploy supports npm specifiers and Node.js compatibility layers from the Deno runtime. However, the bundling process in [`cli/tools/deploy.rs`](https://github.com/denoland/deno/blob/main/cli/tools/deploy.rs) validates that all imports resolve correctly during packaging. Modules requiring native Node.js addons or file system operations violating the Deno permissions model will fail validation before upload.

### How do I rollback to a previous deployment?

Deno Deploy creates **immutable deployments** where each upload receives a unique URL (e.g., `https://<project>-<hash>.deno.dev`). To rollback, redirect traffic to the previous deployment's URL via the dashboard or DNS configuration. The platform retains historical versions indefinitely, allowing instant reversions without re-uploading code.