Skip to main contentSkip to navigation
[email protected]
Client AreaSupport
Hosting Mammoth
HostingMammothYour Data, Our Responsibility
Home
Solutions
Hosting Services
Store
Pricing
About
Blog
API
Contact

Stay Ahead of the Curve

Get the latest insights on cybersecurity, AI innovations, and enterprise data solutions delivered to your inbox.

Hosting Mammoth
HostingMammothEnterprise Solutions

Enterprise-grade data solutions. Hosting, recovery, cybersecurity, and AI-powered services for businesses worldwide.

[email protected]
Sun - Fri, 9:00am - 5:00pm

Services

  • Cloud Hosting
  • Data Recovery
  • Cybersecurity
  • Legal Support
  • MSP Services
  • Web Development
  • AI Services
  • Free Server Migration

Hosting

  • VPS Hosting (NVMe SSD)
  • VDS Hosting (NVMe)
  • Storage VPS (High SSD)
  • GPU Servers
  • Managed Services
  • Cloud Firewall
  • Load Balancer
  • One-Click Apps
  • n8n Hosting
  • Object Storage
  • FAQ

Company

  • Store
  • Pricing
  • About Us
  • Locations
  • Blog
  • Testimonials
  • Contact
  • Affiliate Program
  • White-Label
  • Terms of Service
  • Privacy Policy
  • Browser Cookies
  • SLA

Support

  • Client Area
  • Submit Ticket
  • Knowledge Base
  • Server Status
  • API Documentation

© 2026 Hosting Mammoth. All rights reserved.

Knowledge Base
Getting StartedAccount ManagementVPS HostingGPU ServersStorage VPSCloud FirewallLoad BalancerServer ManagementBilling & PaymentsSupport & TicketsAffiliate ProgramReseller ProgramMarketplace & Appsn8n HostingManaged ServicesServer MigrationAPI & DevelopersSecurityTroubleshootingGlossaryInstall Guides
  1. Home
  2. /
  3. Support
  4. /
  5. Install Guides
  6. /
  7. How To Install Deno Ubuntu
GUIDEInstall Guides

How to Install Deno on Ubuntu 24.04 VPS: TypeScript Runtime Production Setup

23 min read

How to Install Deno on Ubuntu 24.04 VPS — TypeScript Runtime Production Setup

Deno is a modern runtime for JavaScript, TypeScript, and WebAssembly built by Ryan Dahl, the original creator of Node.js. It addresses the architectural regrets of Node head-on: a secure-by-default permission model, first-class TypeScript support with no build step, web-standard APIs, and a single self-contained binary that ships with a formatter, linter, test runner, and bundler. This guide walks you through installing Deno 2.x on an Ubuntu 24.04 VPS, configuring it for production with systemd and Nginx, and shipping a TypeScript service that you can actually trust in front of real traffic.

Want to skip the manual setup? Deploy your TypeScript workloads on the CloudCore Starter VPS with NVMe SSD and EU/US locations — the ideal footprint for Deno services.

Table of Contents

  • What is Deno?
  • Why Run Deno on Your Own VPS?
  • Prerequisites
  • Step 1: Update System Packages
  • Step 2: Install Deno via the Official Script
  • Step 3: Configure PATH and Shell Completions
  • Step 4: Verify the Installation
  • Step 5: Write and Run Your First Deno App
  • Step 6: Work with npm Packages and Node Compatibility
  • Step 7: Pick a Web Framework — Fresh, Oak, or Hono
  • Step 8: Understand the Permission Model
  • Step 9: Compile to a Single Binary with deno compile
  • Step 10: Run Deno as a systemd Service
  • Step 11: Put Nginx in Front as a Reverse Proxy
  • Step 12: Use Deno KV as a Built-in Database
  • Upgrading Deno
  • Troubleshooting
  • FAQ
  • Next Steps
  • What is Deno?

    Deno is an open-source runtime for JavaScript, TypeScript, and WebAssembly written in Rust, built on top of the V8 engine and the Tokio async runtime. It was first released in 2018 and reached its 2.0 milestone in late 2024, which brought full backwards compatibility with Node.js and npm while keeping Deno's original philosophy intact.

    Unlike Node.js, Deno treats TypeScript as a first-class citizen. You can run a .ts file directly with deno run server.ts — there is no tsc, no ts-node, no tsconfig.json minefield. Deno handles type-checking, bundling, and caching transparently. It ships as a single binary with zero dependencies and includes a formatter (deno fmt), linter (deno lint), test runner (deno test), bundler (deno bundle), doc generator (deno doc), and package installer (deno install) built in. There is no node_modules sprawl by default: dependencies are cached globally and imported by URL or through an import_map.json or deno.json configuration.

    Deno's standard library and third-party ecosystem rely on web-standard APIs wherever possible. fetch, Request, Response, URL, crypto.subtle, WebSocket, ReadableStream, and FormData all work identically to how they work in browsers. Code you write for Deno often runs unchanged on Cloudflare Workers, Bun, or in a browser. The team also maintains Deno Deploy, an edge platform for Deno apps, and Deno KV, a built-in key-value store backed by FoundationDB on Deno Deploy and SQLite locally.

    Why Run Deno on Your Own VPS?

    Deno Deploy is convenient, but running Deno on your own VPS gives you advantages that a managed edge platform cannot match:

    • Full control over the runtime -- Pin any Deno version, run multiple services side by side, customize resource limits, and inspect logs without a vendor dashboard.
    • No cold starts -- A long-lived Deno process on a VPS responds to the first request at the same speed as the 10,000th. Edge platforms can introduce cold-start latency for infrequently hit endpoints.
    • Predictable flat pricing -- A VPS costs the same regardless of how many requests you serve. No per-request, per-GB-hour, or per-CPU-ms billing.
    • Run any binary alongside your app -- Put Postgres, Redis, a cron worker, or a background queue on the same box. Edge platforms typically restrict you to stateless functions.
    • Persistent filesystem and sockets -- Write to disk, open raw TCP, run WebSocket servers, and bind privileged ports. All of this is unrestricted on your VPS.
    • GDPR-friendly data residency -- Pick a specific data center region and know exactly where your users' data lives end to end.

    Deno vs. Node.js vs. Bun — At a Glance

    FeatureDeno 2.xNode.js 22 LTSBun 1.x
    TypeScript without a build stepYes (native)No (requires loader)Yes (native)
    Permission model (deny-by-default)YesNoNo
    Single-file binary compileYes (deno compile)No (external tools)Yes (bun build --compile)
    npm compatibilityYes (via npm: specifiers)NativeYes
    Built-in formatter / linter / test runnerYesNoPartial
    Built-in KV storeYes (Deno KV)NoNo
    Web-standard fetch / Request / ResponseYesYes (recent versions)Yes
    Package managerBuilt-innpm / pnpm / yarnBuilt-in
    Memory footprint (idle "hello world")~35 MB~50 MB~40 MB

    Prerequisites

    Before you begin, make sure you have:

    • A VPS running Ubuntu 24.04 LTS with root or sudo access
    • SSH access to the server
    • At least 1 GB of RAM (2 GB+ recommended for comfortable development and compilation)
    • A domain name pointed at the server if you plan to expose the service publicly via Nginx
    Recommended Plan: CloudCore Starter
    >
    Deno is light. For a production TypeScript API serving a few hundred requests per second, the CloudCore Starter plan is more than enough:
    >
    - 2 vCPU cores
    - 4 GB RAM
    - 50 GB NVMe SSD
    - Unmetered bandwidth
    >
    Scale up only when your workload actually demands it — Deno's per-request memory overhead is small enough that most apps never outgrow a Starter-class VPS.

    Connect to your server via SSH to get started:

    bash
    ssh root@your-server-ip

    Step 1: Update System Packages

    Refresh the package index and apply available security updates before installing anything new:

    bash
    sudo apt update && sudo apt upgrade -y

    Install the two utilities the Deno installer needs (curl and unzip):

    bash
    sudo apt install -y curl unzip

    If the kernel was upgraded, reboot before continuing:

    bash
    sudo reboot

    Step 2: Install Deno via the Official Script

    Deno distributes a one-line installer that downloads the correct pre-built binary for your architecture (amd64 or arm64), verifies it, and drops it into ~/.deno/bin. Run it as a regular (non-root) user — installing into your home directory avoids needing sudo and keeps the binary easy to upgrade.

    bash
    curl -fsSL https://deno.land/install.sh | sh

    Expected output:

    text
    ######################################################################## 100.0%
    Archive:  /root/.deno/bin/deno.zip
      inflating: /root/.deno/bin/deno
    Deno was installed successfully to /root/.deno/bin/deno

    Manually add the directory to your $HOME/.bashrc (or similar): export DENO_INSTALL="/root/.deno" export PATH="$DENO_INSTALL/bin:$PATH"

    The installer places the binary at ~/.deno/bin/deno and prints the exact lines you need to add to your shell configuration. No systemd service is created at this stage — Deno is a runtime, not a long-running daemon, so we wire it into systemd later when we have an actual app to run.

    Installing for All Users (Optional)

    If you want every user on the system to have access to the same Deno binary, move it to /usr/local/bin:

    bash
    sudo mv ~/.deno/bin/deno /usr/local/bin/deno
    sudo chmod +x /usr/local/bin/deno

    This is useful when the systemd service runs as a dedicated deno system user that does not share your shell configuration.

    Step 3: Configure PATH and Shell Completions

    Add Deno to your PATH so you can run deno from any directory. Append the following to ~/.bashrc (or ~/.zshrc if you use zsh):

    bash
    cat >> ~/.bashrc <<'EOF'
    export DENO_INSTALL="$HOME/.deno"
    export PATH="$DENO_INSTALL/bin:$PATH"
    EOF

    Reload your shell configuration:

    bash
    source ~/.bashrc

    Install shell completions so tab-completion works for deno subcommands:

    bash
    deno completions bash | sudo tee /etc/bash_completion.d/deno > /dev/null

    Open a new shell for the completions to take effect.

    Step 4: Verify the Installation

    Confirm Deno is on your PATH and reports a sensible version:

    bash
    deno --version

    Expected output:

    text
    deno 2.1.4 (stable, release, x86_64-unknown-linux-gnu)
    v8 13.0.245.12-rusty
    typescript 5.6.2

    The three lines show the Deno version, the bundled V8 engine version, and the bundled TypeScript compiler version. You do not install TypeScript separately — whatever version Deno ships with is the one your code runs against.

    Run the built-in REPL to make sure the runtime is healthy:

    bash
    deno

    You will see a prompt like:

    text
    Deno 2.1.4
    exit using ctrl+d, ctrl+c, or close()
    REPL is running with all permissions allowed.
    To specify permissions, run deno repl with allow flags.
    >

    Type a quick expression and press Enter:

    text
    > const x: number = 42; x * 2
    84

    Exit with Ctrl+D.

    Step 5: Write and Run Your First Deno App

    Create a project directory and a minimal HTTP server in TypeScript:

    bash
    mkdir -p ~/apps/hello-deno && cd ~/apps/hello-deno
    bash
    cat > server.ts <<'EOF'
    const port = 8000;

    Deno.serve({ port }, (req: Request) => { const url = new URL(req.url); return new Response( JSON.stringify({ message: "Hello from Deno on Ubuntu 24.04", path: url.pathname, timestamp: new Date().toISOString(), }), { headers: { "content-type": "application/json" } }, ); });

    console.log(Listening on http://localhost:${port}); EOF

    Run it:

    bash
    deno run --allow-net server.ts

    Expected output:

    text
    Listening on http://localhost:8000

    From another terminal (or the same one, after backgrounding the server), hit the endpoint:

    bash
    curl http://localhost:8000/health

    Expected output:

    json
    {"message":"Hello from Deno on Ubuntu 24.04","path":"/health","timestamp":"2026-04-16T10:00:00.000Z"}

    Notice two things:

  • No package.json, no tsconfig.json, no npm install. Deno ran the TypeScript file directly.
  • --allow-net was required. Without the flag, Deno would have refused to open a network socket. This is the permission model in action, which we cover in Step 8.
  • Add a deno.json for Tasks and Imports

    For anything beyond a single file, create a deno.json at the project root:

    bash
    cat > deno.json <<'EOF'
    {
      "tasks": {
        "dev": "deno run --allow-net --watch server.ts",
        "start": "deno run --allow-net server.ts",
        "test": "deno test --allow-net"
      },
      "imports": {
        "@std/http": "jsr:@std/http@^1.0.0",
        "@std/assert": "jsr:@std/assert@^1.0.0"
      }
    }
    EOF

    Now you can run the dev server (with file-watch auto-reload) via a task:

    bash
    deno task dev

    The imports field is an import map. You can reference @std/http from any file in the project without hardcoding URLs, and Deno caches the resolved modules in ~/.cache/deno.

    Step 6: Work with npm Packages and Node Compatibility

    Deno 2 can import any npm package through the npm: specifier. No npm install, no node_modules folder (unless you ask for one), no package-lock.

    Use Zod (a popular schema validator) directly in your TypeScript:

    typescript
    import { z } from "npm:[email protected]";

    const User = z.object({ email: z.string().email(), age: z.number().int().positive(), });

    const parsed = User.parse({ email: "[email protected]", age: 30 }); console.log(parsed);

    Run it:

    bash
    deno run --allow-net --allow-read --allow-env main.ts

    If you prefer the traditional node_modules layout (some tools and editor plugins expect it), enable it in deno.json:

    json
    {
      "nodeModulesDir": "auto"
    }

    Installing CLI Tools Globally

    deno install turns any script into a global command. Install a TypeScript-based CLI once and call it from anywhere:

    bash
    deno install --global --allow-net --allow-read -n my-cli https://raw.githubusercontent.com/example/cli/main/mod.ts

    The -n flag names the binary. Make sure ~/.deno/bin is on your PATH (configured in Step 3) so the installed command is callable.

    JSR: The Official Deno Registry

    JSR is Deno's native registry. Packages published to JSR are TypeScript-first and work across Deno, Node, Bun, and the browser. Use them via jsr: specifiers:

    typescript
    import { serveDir } from "jsr:@std/http/file-server";

    JSR handles versioning, provenance, and score-based quality signals out of the box.

    Step 7: Pick a Web Framework — Fresh, Oak, or Hono

    For anything larger than a single endpoint, a framework cuts the boilerplate dramatically.

    Fresh — Full-Stack, Islands Architecture

    Fresh is Deno's official full-stack framework. It uses an islands architecture (ship minimal JavaScript, hydrate only interactive components), server-side rendering with Preact, and file-system routing.

    Scaffold a new project:

    bash
    deno run -A -r https://fresh.deno.dev my-fresh-app
    cd my-fresh-app
    deno task start

    Fresh is ideal for content-driven sites, marketing pages, dashboards, and SSR-first apps where ship-less-JS is a priority.

    Oak — Koa-Style Middleware

    Oak is the closest thing Deno has to Express or Koa. Middleware-based, explicit router, minimal magic:

    typescript
    import { Application, Router } from "jsr:@oak/oak";

    const router = new Router(); router.get("/", (ctx) => { ctx.response.body = { ok: true }; });

    const app = new Application(); app.use(router.routes()); app.use(router.allowedMethods()); await app.listen({ port: 8000 });

    Oak is the pragmatic choice for traditional REST APIs.

    Hono — Ultra-Fast, Runtime-Agnostic

    Hono runs on Deno, Bun, Node, Cloudflare Workers, and Vercel Edge — the same code, everywhere. It is the fastest router in the Deno ecosystem:

    typescript
    import { Hono } from "npm:hono";

    const app = new Hono(); app.get("/", (c) => c.json({ ok: true, runtime: "deno" }));

    Deno.serve(app.fetch);

    Pick Hono when you want portability across runtimes or need the best raw throughput.

    Step 8: Understand the Permission Model

    This is Deno's defining feature: a script has no access to anything by default. No network, no disk, no environment variables, no child processes. You grant permissions explicitly via CLI flags.

    The most common flags, with safe scoping:

    FlagPurposeSafe Example
    --allow-netOutbound / listening network--allow-net=api.example.com,:8000
    --allow-readFilesystem read--allow-read=./data,./config
    --allow-writeFilesystem write--allow-write=./logs,./uploads
    --allow-envEnvironment variables--allow-env=PORT,DATABASE_URL
    --allow-runSpawn subprocesses--allow-run=git,ffmpeg
    --allow-sysSystem info (osRelease, hostname, etc.)--allow-sys=hostname,osRelease
    --allow-ffiForeign function interfaceUse sparingly — full native access
    Always prefer scoped permissions. Granting --allow-read=./data means a bug or a supply-chain attack cannot read /etc/shadow. Granting --allow-read alone gives read access to the entire filesystem.

    The -A Shortcut (Use Cautiously)

    deno run -A app.ts grants all permissions. It is convenient in development but defeats the entire purpose in production. Never deploy a systemd unit with -A.

    Pinning Permissions in deno.json

    Deno 2 allows permissions to be specified per-task so you do not have to remember them:

    json
    {
      "tasks": {
        "start": {
          "command": "deno run server.ts",
          "description": "Run the API server"
        }
      }
    }

    Combined with explicit flags in the command string, this gives you a single place to audit what your app can do.

    Step 9: Compile to a Single Binary with deno compile

    One of Deno's killer features is deno compile, which bundles your TypeScript, its dependencies, and the Deno runtime itself into a single self-contained executable. No Deno install required on the target machine.

    Compile the server you wrote in Step 5:

    bash
    deno compile \
      --allow-net \
      --output hello-deno-server \
      server.ts

    Expected output:

    text
    Compile file:///root/apps/hello-deno/server.ts to hello-deno-server

    Check the binary:

    bash
    ls -lh hello-deno-server
    ./hello-deno-server

    Expected output:

    text
    -rwxr-xr-x 1 root root 82M Apr 16 10:00 hello-deno-server
    Listening on http://localhost:8000

    The binary is self-contained (~80 MB — that includes V8 and the TypeScript compiler) and embeds the permissions you specified at compile time. Ship it to any Linux amd64 server and run it. No runtime to install, no node_modules to copy.

    Cross-Compiling

    You can compile for other targets from a single build machine:

    bash
    # Compile for Linux ARM64 (e.g. AWS Graviton, Raspberry Pi 5)
    deno compile --target aarch64-unknown-linux-gnu --output hello-deno-arm64 --allow-net server.ts

    Compile for macOS / Windows

    deno compile --target x86_64-apple-darwin --output hello-deno-mac --allow-net server.ts deno compile --target x86_64-pc-windows-msvc --output hello-deno.exe --allow-net server.ts

    Step 10: Run Deno as a systemd Service

    For production, wire your Deno app into systemd so it restarts on failure, starts on boot, and logs to the journal. You can run the source file directly or the compiled binary — we show the source-file approach below because it is the most common pattern.

    For a deeper walkthrough of systemd itself (unit file anatomy, security hardening, logging), see our companion guide. Hardening systemd services on Ubuntu covers the general pattern we reuse here.

    Create a Dedicated System User

    bash
    sudo useradd --system --create-home --shell /usr/sbin/nologin deno

    Deploy the Application

    bash
    sudo mkdir -p /opt/my-deno-app
    sudo cp server.ts deno.json /opt/my-deno-app/
    sudo chown -R deno:deno /opt/my-deno-app

    Pre-cache dependencies as the deno user so the first request does not pay the download cost:

    bash
    sudo -u deno DENO_DIR=/opt/my-deno-app/.deno deno cache /opt/my-deno-app/server.ts

    Write the systemd Unit

    bash
    sudo tee /etc/systemd/system/my-deno-app.service > /dev/null <<'EOF'
    [Unit]
    Description=My Deno App
    After=network.target

    [Service] Type=simple User=deno Group=deno WorkingDirectory=/opt/my-deno-app Environment="DENO_DIR=/opt/my-deno-app/.deno" Environment="PORT=8000" ExecStart=/usr/local/bin/deno run --allow-net --allow-env=PORT --allow-read=/opt/my-deno-app server.ts Restart=on-failure RestartSec=5s

    Hardening

    NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true ReadWritePaths=/opt/my-deno-app/.deno

    [Install] WantedBy=multi-user.target EOF

    Enable and start the service:

    bash
    sudo systemctl daemon-reload
    sudo systemctl enable --now my-deno-app
    sudo systemctl status my-deno-app

    Expected output (abbreviated):

    text
    ● my-deno-app.service - My Deno App
         Loaded: loaded (/etc/systemd/system/my-deno-app.service; enabled)
         Active: active (running) since Wed 2026-04-16 10:00:00 UTC; 5s ago
       Main PID: 12345 (deno)
          Tasks: 12
         Memory: 38.2M
         CGroup: /system.slice/my-deno-app.service
                 └─12345 /usr/local/bin/deno run --allow-net --allow-env=PORT --allow-read=/opt/my-deno-app server.ts

    Tail the logs:

    bash
    sudo journalctl -u my-deno-app -f

    Step 11: Put Nginx in Front as a Reverse Proxy

    Deno's Deno.serve is production-ready — it handles HTTP/2 and performs extremely well — but you still want Nginx (or Caddy) in front for TLS termination, static asset caching, rate limiting, and as a buffer against slowloris-style attacks. Our full Nginx setup guide walks through installing Nginx, Certbot, and TLS; see How to Install Nginx on Ubuntu 24.04.

    Once Nginx is installed, add a site file for your Deno app:

    bash
    sudo tee /etc/nginx/sites-available/my-deno-app > /dev/null <<'EOF'
    server {
        listen 80;
        server_name app.example.com;

    location / { proxy_pass http://127.0.0.1:8000; proxy_http_version 1.1;

    proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;

    # WebSocket upgrade headers proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade";

    # Streaming-friendly timeouts proxy_buffering off; proxy_read_timeout 300s; } } EOF

    sudo ln -s /etc/nginx/sites-available/my-deno-app /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx

    Obtain a TLS certificate with Certbot:

    bash
    sudo certbot --nginx -d app.example.com

    Your Deno service is now available at https://app.example.com with automatic renewal.

    Step 12: Use Deno KV as a Built-in Database

    Deno KV is a strongly consistent key-value store baked into the runtime. On your own VPS, it is backed by a single SQLite file — you get transactions, secondary indexes, and atomic operations with zero infrastructure.

    typescript
    const kv = await Deno.openKv();

    // Write await kv.set(["users", "alice"], { email: "[email protected]", plan: "pro" });

    // Read const { value } = await kv.get<{ email: string; plan: string }>([ "users", "alice", ]); console.log(value); // { email: "[email protected]", plan: "pro" }

    // Atomic transaction await kv.atomic() .check({ key: ["counters", "visits"], versionstamp: null }) .set(["counters", "visits"], 1n) .commit();

    // Range query for await (const entry of kv.list({ prefix: ["users"] })) { console.log(entry.key, entry.value); }

    Run it with the --unstable-kv flag (KV is stable on Deno Deploy and moving to stable locally):

    bash
    deno run --allow-net --unstable-kv app.ts

    By default, the KV database lives at ~/.cache/deno/location_data/<hash>/kv.sqlite3. For production, pin it to a known path:

    typescript
    const kv = await Deno.openKv("/opt/my-deno-app/data/kv.db");

    Remember to grant --allow-read and --allow-write for that path in your systemd unit.

    Upgrading Deno

    Deno ships updates roughly every two to four weeks. Upgrading is a single command:

    bash
    deno upgrade

    Expected output:

    text
    Looking up latest version
    Found latest version 2.1.6
    Checking https://github.com/denoland/deno/releases/download/v2.1.6/deno-x86_64-unknown-linux-gnu.zip
    Deno is upgrading to version 2.1.6
    Archive:  /tmp/.tmp.abc/deno.zip
      inflating: deno
    Upgraded successfully to Deno v2.1.6

    To pin a specific version (useful in CI or when reproducing a deployment):

    bash
    deno upgrade --version 2.1.4

    If you moved the binary to /usr/local/bin you may need sudo:

    bash
    sudo deno upgrade

    After upgrading, restart any systemd services that run Deno so they pick up the new runtime:

    bash
    sudo systemctl restart my-deno-app

    Troubleshooting

    ProblemCauseSolution
    PermissionDenied: Requires net access to "0.0.0.0:8000"Missing --allow-net flagAdd --allow-net (optionally scoped: --allow-net=:8000) to your deno run command or systemd ExecStart.
    error: Module not found "npm:foo"Typo in specifier or version that does not exist on npmDouble-check on npmjs.com. Pin the version explicitly: npm:[email protected].
    First request to an endpoint is slowDeno is compiling and caching the module graph on first runPre-cache with deno cache server.ts before starting the service. The systemd unit above already does this.
    error: Cannot find name 'Deno' in your editorTypeScript LSP is running in Node modeInstall the Deno VS Code extension and enable it for your workspace, or set "deno.enable": true in .vscode/settings.json.
    deno: command not found after installPATH not updated in current shellsource ~/.bashrc or open a new shell. Verify with echo $PATH that ~/.deno/bin is present.
    High disk usage in ~/.cache/denoDependency cache grows over timeClear with deno clean (removes cached modules; they will re-download on next run).
    Error: Unable to get the contents of the lockfileMissing or corrupt deno.lockDelete deno.lock and re-run deno cache to regenerate it.
    npm package works locally but fails in systemdDENO_DIR points to a directory the systemd user cannot readSet DENO_DIR explicitly in the unit file and pre-cache dependencies as that user (see Step 10).

    Inspecting a Running Deno Process

    Deno exposes an inspector on --inspect=127.0.0.1:9229. You can attach Chrome DevTools (chrome://inspect) for live debugging, profiling, and heap snapshots — identical to Node.js. Only enable the inspector in staging, never in production.

    FAQ

    Is Deno faster than Node.js?

    For raw HTTP throughput on a simple handler, Deno 2 and Node.js 22 are roughly comparable — both typically land within 10–20% of each other depending on the benchmark. Deno wins on startup time (a deno run of a TypeScript file starts faster than node --loader tsx), and Hono on Deno consistently tops framework benchmarks. Node wins on ecosystem maturity and tooling for very specific workloads. For most CRUD APIs and SSR workloads, performance is not the deciding factor — developer experience and the permission model are.

    Can I use my existing npm packages?

    Yes. Deno 2 supports the entire npm ecosystem via npm: specifiers and maintains near-complete compatibility with Node.js built-ins (node:fs, node:crypto, node:stream, etc.). Packages that rely on the V8 engine work natively; packages that use native C++ addons via node-gyp are supported through Deno's Node-API compatibility layer. Some edge cases around __dirname, dynamic require, and CommonJS-only packages still need workarounds — the Deno compatibility matrix lists known issues.

    Do I need tsconfig.json?

    No. Deno has sensible TypeScript defaults baked in. You can override them in the compilerOptions field of deno.json if you need to (for example, to enable jsx for a Preact project), but the vast majority of apps never touch this. There is no build step, no tsc, no ts-node — deno run foo.ts just works.

    Is Deno production-ready?

    Yes. Deno powers services at Slack, Netlify, GitHub, and Supabase (among others), and Deno Deploy runs on the same runtime. The Deno 2.0 release in October 2024 froze the stable API surface and committed to backwards compatibility. Running Deno on a VPS with systemd and Nginx is a standard, boring deployment — exactly what production should look like.

    How does Deno KV compare to Redis or Postgres?

    Deno KV is a strongly consistent key-value store with transactional guarantees. It is perfect for sessions, rate limits, feature flags, caching, job queues (via kv.watch), and small-to-medium app state. It is not a replacement for a relational database (no joins, no SQL) or for Redis at extreme scale (no pub/sub, no Lua scripting). Use Deno KV for 80% of "I need a place to stash some state" needs and reach for Postgres or Redis when your access patterns demand them.

    Should I compile with deno compile or run from source?

    Compile when you want immutable, reproducible deployments or when the target environment has no Deno runtime. Run from source when you deploy frequently (no compile step to wait on), when you want deno upgrade to benefit every service automatically, or when you need to share the module cache across multiple services on the same box. Most VPS deployments use source + systemd, which is what this guide covers.

    Next Steps

    With Deno running on your VPS, here are the highest-leverage things to do next:

    • Set up CI/CD with GitHub Actions -- Use the official denoland/setup-deno action to run deno fmt --check, deno lint, and deno test on every push. Deploy by SSH-ing to your VPS and running git pull && systemctl restart my-deno-app.
    • Add observability -- Export OpenTelemetry traces from your Deno app (native support landed in Deno 2.1) and point them at a self-hosted Grafana stack. Deno emits HTTP server spans automatically with zero code changes.
    • Build a Fresh site for your product -- The Fresh framework is the fastest way to ship a TypeScript-native, SSR-first website with islands-based interactivity. Deploy it alongside your API on the same VPS.
    • Explore Deno's standard library -- jsr.io/@std is curated, audited, and versioned. Modules for HTTP, file system, cryptography, CSV, YAML, UUID, and more — no npm risk, no supply-chain surprises.
    • Read the official docs -- docs.deno.com is genuinely excellent. The runtime reference, the manual, and the "by example" cookbook cover every realistic production scenario.

    Ready to Run Deno in Production?
    >
    The CloudCore Starter VPS gives you 2 vCPU, 4 GB RAM, and 50 GB NVMe — the sweet spot for a TypeScript API, a Fresh frontend, and Deno KV, all on one box with room to grow.
    >
    - NVMe SSD storage for fast cold starts on compiled Deno binaries
    - Unmetered bandwidth — stream as much SSR HTML as you like
    - EU and US data-center locations for low-latency user traffic
    - Full root access — install any Deno version, run any number of services
    >
    Deploy Your Deno VPS Now and have your first TypeScript service in production within the next 15 minutes.

    Was this article helpful?

    ← Back to Install GuidesBrowse all categories →

    Still have questions?

    Contact Support →Submit a Ticket