Complete Deno Deploy Cheat Sheet: Setup, Deployment & Best Practices Guide

Introduction

Deno Deploy is a serverless platform for running JavaScript, TypeScript, and WebAssembly applications at the edge. Built specifically for Deno runtime, it provides fast global deployment with zero configuration, automatic HTTPS, and built-in CDN capabilities.

Why It Matters:

  • Zero-config deployment with Git integration
  • Global edge network for low latency
  • Built-in TypeScript support without compilation
  • Automatic scaling and HTTPS certificates
  • Pay-per-use pricing model
  • Native Web APIs and modern JavaScript features

Core Concepts & Principles

Key Features

  • Edge Runtime: Code runs close to users globally
  • V8 Isolates: Fast, secure execution environment
  • Git Integration: Automatic deployments from GitHub/GitLab
  • Web Standards: Built on standard Web APIs
  • Zero Cold Starts: Instant function execution
  • Built-in Monitoring: Performance and error tracking

Deployment Models

  • Git Integration: Automatic deployments from repositories
  • CLI Deployment: Direct deployment via command line
  • Playground: Browser-based code editor and deployment
  • GitHub Actions: CI/CD pipeline integration

Supported Runtimes

  • JavaScript (ES2022): Modern JS features
  • TypeScript: Native support without build step
  • WebAssembly: WASM module execution
  • Import Maps: Dependency management
  • NPM Modules: Limited npm package support

Getting Started: Step-by-Step Setup

Phase 1: Account Setup

  1. Create Account

    # Visit https://dash.deno.com
    # Sign up with GitHub, GitLab, or email
    # Verify email address
    
  2. Install Deno CLI (Optional but recommended)

    # macOS/Linux
    curl -fsSL https://deno.land/x/install/install.sh | sh
    
    # Windows (PowerShell)
    irm https://deno.land/install.ps1 | iex
    
    # Via package managers
    brew install deno        # macOS
    choco install deno       # Windows
    scoop install deno       # Windows
    
  3. Install Deployctl

    deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -r -f https://deno.land/x/deploy/deployctl.ts
    

Phase 2: Project Structure

my-deno-app/
├── main.ts              # Entry point
├── deno.json           # Deno configuration
├── import_map.json     # Dependency mapping
├── static/             # Static assets
│   ├── style.css
│   └── script.js
└── api/                # API routes
    ├── hello.ts
    └── users.ts

Phase 3: Basic Application

// main.ts - Basic HTTP server
import { serve } from "https://deno.land/std@0.208.0/http/server.ts";

const handler = (req: Request): Response => {
  const url = new URL(req.url);
  
  if (url.pathname === "/") {
    return new Response("Hello from Deno Deploy!", {
      headers: { "content-type": "text/plain" },
    });
  }
  
  if (url.pathname === "/api/time") {
    return new Response(JSON.stringify({ 
      time: new Date().toISOString() 
    }), {
      headers: { "content-type": "application/json" },
    });
  }
  
  return new Response("Not Found", { status: 404 });
};

serve(handler);

Deployment Methods

Method 1: Git Integration (Recommended)

StepActionDetails
1Push to RepositoryCommit code to GitHub/GitLab
2Connect RepositoryLink repo in Deno Deploy dashboard
3Configure BuildSet entry point (usually main.ts)
4DeployAutomatic deployment on git push
# Example workflow
git add .
git commit -m "Initial deployment"
git push origin main
# Automatic deployment triggers

Method 2: CLI Deployment

# Deploy current directory
deployctl deploy --project=my-app main.ts

# Deploy with custom domain
deployctl deploy --project=my-app --prod main.ts

# Deploy specific files
deployctl deploy --project=my-app --include=main.ts,static/ main.ts

Method 3: Playground Deployment

  • Visit dash.deno.com
  • Create new playground
  • Write/paste code
  • Click “Deploy” button
  • Get instant deployment URL

Configuration Files

deno.json Configuration

{
  "compilerOptions": {
    "allowJs": true,
    "lib": ["deno.window"],
    "strict": true
  },
  "imports": {
    "std/": "https://deno.land/std@0.208.0/",
    "fresh": "https://deno.land/x/fresh@1.6.0/",
    "oak": "https://deno.land/x/oak@v12.6.1/"
  },
  "tasks": {
    "dev": "deno run --allow-net --allow-read --watch main.ts",
    "start": "deno run --allow-net --allow-read main.ts"
  },
  "fmt": {
    "files": {
      "include": ["src/"],
      "exclude": ["static/"]
    }
  },
  "lint": {
    "files": {
      "include": ["src/"],
      "exclude": ["static/"]
    }
  }
}

Import Map Example

{
  "imports": {
    "std/": "https://deno.land/std@0.208.0/",
    "preact": "https://esm.sh/preact@10.19.2",
    "preact/": "https://esm.sh/preact@10.19.2/",
    "@supabase/supabase-js": "https://esm.sh/@supabase/supabase-js@2.38.4",
    "postgres": "https://deno.land/x/postgres@v0.17.0/mod.ts"
  }
}

Common Use Cases & Examples

Static Site Hosting

// main.ts - Static file server
import { serveDir } from "https://deno.land/std@0.208.0/http/file_server.ts";

Deno.serve((req: Request) => {
  return serveDir(req, {
    fsRoot: "static",
    urlRoot: "",
  });
});

API Endpoints

// api/users.ts
interface User {
  id: number;
  name: string;
  email: string;
}

const users: User[] = [
  { id: 1, name: "John Doe", email: "john@example.com" },
  { id: 2, name: "Jane Smith", email: "jane@example.com" },
];

export const handler = (req: Request): Response => {
  const url = new URL(req.url);
  const method = req.method;

  if (method === "GET") {
    return new Response(JSON.stringify(users), {
      headers: { "content-type": "application/json" },
    });
  }

  if (method === "POST") {
    // Handle user creation
    return new Response(JSON.stringify({ success: true }), {
      status: 201,
      headers: { "content-type": "application/json" },
    });
  }

  return new Response("Method not allowed", { status: 405 });
};

Serverless Functions

// functions/webhook.ts
export default async function handler(req: Request): Promise<Response> {
  if (req.method !== "POST") {
    return new Response("Method not allowed", { status: 405 });
  }

  const body = await req.json();
  
  // Process webhook data
  console.log("Webhook received:", body);
  
  // Example: Send to external service
  await fetch("https://api.external-service.com/webhook", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  });

  return new Response("OK");
}

Database Integration

// Example with Supabase
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.38.4";

const supabase = createClient(
  Deno.env.get("SUPABASE_URL")!,
  Deno.env.get("SUPABASE_ANON_KEY")!
);

export const handler = async (req: Request): Promise<Response> => {
  const { data, error } = await supabase
    .from("users")
    .select("*");

  if (error) {
    return new Response(JSON.stringify({ error: error.message }), {
      status: 500,
      headers: { "content-type": "application/json" },
    });
  }

  return new Response(JSON.stringify(data), {
    headers: { "content-type": "application/json" },
  });
};

Environment Variables & Secrets

Setting Environment Variables

# Via Dashboard
# 1. Go to project settings
# 2. Add environment variables
# 3. Redeploy to apply changes

# Via CLI
deployctl deploy --project=my-app --env-file=.env main.ts

Using Environment Variables

// Access environment variables
const apiKey = Deno.env.get("API_KEY");
const dbUrl = Deno.env.get("DATABASE_URL");

// With fallback values
const port = Deno.env.get("PORT") || "8000";
const environment = Deno.env.get("ENVIRONMENT") || "development";

// Validation
if (!apiKey) {
  throw new Error("API_KEY environment variable is required");
}

.env File Example

# .env (for local development only)
API_KEY=your-api-key-here
DATABASE_URL=postgresql://user:pass@host:port/db
SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-anon-key

Performance Optimization

Code Optimization

// Use streaming responses for large data
export const handler = (req: Request): Response => {
  const stream = new ReadableStream({
    start(controller) {
      // Stream large JSON data
      controller.enqueue(`{"items":[`);
      
      for (let i = 0; i < 1000; i++) {
        const item = JSON.stringify({ id: i, data: `item-${i}` });
        controller.enqueue(item);
        if (i < 999) controller.enqueue(",");
      }
      
      controller.enqueue(`]}`);
      controller.close();
    },
  });

  return new Response(stream, {
    headers: { "content-type": "application/json" },
  });
};

Caching Strategies

// Cache responses
const cache = new Map<string, { data: any; expires: number }>();

export const handler = async (req: Request): Promise<Response> => {
  const url = new URL(req.url);
  const cacheKey = url.pathname;
  
  // Check cache
  const cached = cache.get(cacheKey);
  if (cached && cached.expires > Date.now()) {
    return new Response(JSON.stringify(cached.data), {
      headers: { 
        "content-type": "application/json",
        "x-cache": "HIT"
      },
    });
  }
  
  // Fetch fresh data
  const data = await fetchData();
  
  // Cache for 5 minutes
  cache.set(cacheKey, {
    data,
    expires: Date.now() + 5 * 60 * 1000
  });
  
  return new Response(JSON.stringify(data), {
    headers: { 
      "content-type": "application/json",
      "x-cache": "MISS"
    },
  });
};

Common Challenges & Solutions

Challenge 1: Cold Start Performance

Solutions:

  • Keep functions lightweight
  • Minimize external dependencies
  • Use dynamic imports for heavy modules
  • Implement connection pooling

Challenge 2: Memory Limitations

Solutions:

  • Stream large responses instead of buffering
  • Clean up unused variables and connections
  • Use efficient data structures
  • Monitor memory usage

Challenge 3: NPM Module Compatibility

Solutions:

  • Use ESM-compatible modules from esm.sh
  • Check Deno compatibility before using
  • Prefer Deno-native alternatives
  • Use import maps for dependency management

Challenge 4: Local Development Differences

Solutions:

  • Use same Deno version locally and in deploy
  • Test with –allow-net flag restrictions
  • Use environment variables consistently
  • Implement feature flags for environment differences

Challenge 5: Debugging Production Issues

Solutions:

  • Use structured logging with JSON
  • Implement proper error handling
  • Monitor function execution times
  • Use Deno Deploy’s built-in analytics

Best Practices & Tips

Code Organization

  • Single Responsibility: Keep functions focused and small
  • Modular Structure: Separate concerns into different files
  • Type Safety: Use TypeScript for better development experience
  • Error Handling: Always handle errors gracefully

Security

  • Environment Variables: Never commit secrets to code
  • Input Validation: Validate all incoming data
  • CORS Headers: Set appropriate CORS policies
  • Rate Limiting: Implement request throttling for APIs

Performance

  • Minimize Dependencies: Only import what you need
  • Edge Optimization: Leverage global deployment
  • Caching: Implement appropriate caching strategies
  • Streaming: Use streaming for large responses

Monitoring & Debugging

  • Structured Logging: Use consistent log formats
  • Error Tracking: Monitor and alert on errors
  • Performance Metrics: Track response times and memory usage
  • Health Checks: Implement endpoint monitoring

CLI Commands Reference

Basic Commands

# Check Deno version
deno --version

# Run project locally
deno run --allow-net --allow-read main.ts

# Format code
deno fmt

# Lint code
deno lint

# Run tests
deno test

# Check for updates
deno upgrade

Deployment Commands

# Deploy project
deployctl deploy --project=my-app main.ts

# Deploy to production
deployctl deploy --project=my-app --prod main.ts

# Deploy with environment file
deployctl deploy --project=my-app --env-file=.env main.ts

# List deployments
deployctl deployments --project=my-app

# View logs
deployctl logs --project=my-app

Resources for Further Learning

Official Documentation

Tutorials & Guides

  • Fresh Framework with Deno Deploy
  • Building REST APIs with Deno
  • Serverless Functions Best Practices
  • TypeScript in Deno Deploy

Community Resources

Example Projects

Related Tools

  • Fresh: Full-stack web framework for Deno
  • Aleph.js: React framework for Deno
  • Oak: Middleware framework for HTTP servers
  • Cliffy: Command line framework for Deno

Last Updated: May 2025 | This cheatsheet covers Deno Deploy fundamentals through advanced deployment strategies.

Scroll to Top