diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..6efa375
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+  "deno.enable": true,
+  "deno.unstable": true,
+  "deno.lint": true
+}
diff --git a/Dockerfile b/Dockerfile
index ed2e089..5ccd8c7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,10 +1,10 @@
-FROM denoland/deno:alpine-1.26.1
+FROM denoland/deno:debian-1.26.1
 
 
 RUN deno install --allow-read --allow-write --allow-env --allow-net --allow-run --no-check -r -f https://deno.land/x/deploy/deployctl.ts
 
-COPY run.sh /bin/
-RUN chmod +x /bin/run.sh
+COPY run.ts /bin/
+RUN chmod +x /bin/run.ts
 
 USER deno
-CMD ["/bin/run.sh"]
\ No newline at end of file
+CMD ["/bin/run.ts"]
\ No newline at end of file
diff --git a/README.md b/README.md
index d2b6ffc..aac90be 100644
--- a/README.md
+++ b/README.md
@@ -2,25 +2,27 @@
 
 [![Build Status](https://ci.git.froth.zone/api/badges/sam/drone-deno-deploy/status.svg)](https://ci.git.froth.zone/sam/drone-deno-deploy)
 
-A [Drone](https://drone.io) and [Woodpecker](https://woodpecker-ci.org/) plugin to deploy a JavaScript/TypeScript application to [Deno Deploy](https://deno.com/deploy).
+A [Drone](https://drone.io) and [Woodpecker](https://woodpecker-ci.org/) plugin
+to deploy a JavaScript/TypeScript application to
+[Deno Deploy](https://deno.com/deploy).
 
 This is built on top of [deployctl](https://deno.com/deploy/docs/deployctl).
 
 ## Example Usage
 
 ```yaml
-  - name: Deploy to Deno Deploy (prod)
-    image: git.froth.zone/sam/drone-deno-deploy
-    environment:
-      DENO_DEPLOY_TOKEN:
-        from_secret: DENO_DEPLOY_TOKEN
-    settings:
-      project: drone-deploy
-      entrypoint: server/main.ts
-      production: true
-    when:
-      branch:
-      - master
-      event:
-      - push
+- name: Deploy to Deno Deploy (prod)
+  image: git.froth.zone/sam/drone-deno-deploy
+  environment:
+    DENO_DEPLOY_TOKEN:
+      from_secret: DENO_DEPLOY_TOKEN
+  settings:
+    project: drone-deploy
+    entrypoint: server/main.ts
+    production: true
+  when:
+    branch:
+    - master
+    event:
+    - push
 ```
diff --git a/example b/example
index d5fe3ee..c1d62aa 160000
--- a/example
+++ b/example
@@ -1 +1 @@
-Subproject commit d5fe3ee49ee63651ba7f2f0884e71cbae33d6411
+Subproject commit c1d62aac006148041dac7187d7f08a93aa2e6e25
diff --git a/run.sh b/run.sh
deleted file mode 100755
index aea3d2b..0000000
--- a/run.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-set -e
-# Also broken
-if [ -z "$PLUGIN_DENO_DEPLOY_TOKEN" ] && [ -z "$DENO_DEPLOY_TOKEN" ]; then
-# if [ -z "$DENO_DEPLOY_TOKEN" ]; then
-  printf "A Deno Deploy token is required.\n\nGo to https://dash.deno.com/account#access-tokens to get one and set DENO_DEPLOY_TOKEN.\n"
-  exit 1
-fi
-
-if [ -z "$PLUGIN_ENTRYPOINT" ]; then
-  echo "An entrypoint is required."
-  exit 1
-fi
-
-if [ -z "$PLUGIN_PROJECT" ]; then
-  echo "Please set an entrypoint to use (Settings Name: project)"
-  exit 1
-fi
-
-FLAGS="$FLAGS -p=$PLUGIN_PROJECT"
-
-# This is broken
-if [ -n "$PLUGIN_DENO_DEPLOY_TOKEN" ]; then
-  FLAGS="$FLAGS --token=$PLUGIN_DENO_DEPLOY_TOKEN"
-fi
-
-if [ -n "$PLUGIN_EXCLUDE" ]; then
-  FLAGS="$FLAGS --exclude=$PLUGIN_EXCLUDE"
-fi
-
-if [ -n "$PLUGIN_INCLUDE" ]; then
-  FLAGS="$FLAGS --include=$PLUGIN_INCLUDE"
-fi
-
-if [ -n "$PLUGIN_IMPORT_MAP" ]; then
-  FLAGS="$FLAGS --import-map=$PLUGIN_IMPORT_MAP"
-fi
-
-if [ -n "$PLUGIN_NO_STATIC" ]; then
-  FLAGS="$FLAGS --no-static"
-fi
-
-if [ -n "$PLUGIN_PROD" ] || [ -n "$PLUGIN_PRODUCTION" ]; then
-  FLAGS="$FLAGS --prod"
-fi
-
-
-# This disgusting monstrosity returns where the build was deployed to. Useful for testing and PRs.
-deployctl deploy ${FLAGS} "$PLUGIN_ENTRYPOINT"
-
diff --git a/run.ts b/run.ts
new file mode 100755
index 0000000..9434de3
--- /dev/null
+++ b/run.ts
@@ -0,0 +1,81 @@
+#!/usr/bin/env -S deno run --allow-run --allow-env
+
+const env = Deno.env.toObject();
+
+if (!env["PLUGIN_DENO_DEPLOY_TOKEN"] && !env["DENO_DEPLOY_TOKEN"]) {
+  console.error(
+    "A Deno Deploy token is required.\n\nGo to https://dash.deno.com/account#access-tokens to get one and set DENO_DEPLOY_TOKEN.",
+  );
+  Deno.exit(1);
+}
+
+if (!env["PLUGIN_ENTRYPOINT"]) {
+  console.error("An entrypoint is required");
+  Deno.exit(1);
+}
+
+if (!env["PLUGIN_PROJECT"]) {
+  console.error("An project is required");
+  Deno.exit(1);
+}
+
+const flags = [`-p=${env["PLUGIN_PROJECT"]}`];
+
+if (env["PLUGIN_DENO_DEPLOY_TOKEN"]) {
+  flags.push(`--token=${env["PLUGIN_DENO_DEPLOY_TOKEN"]}`);
+}
+
+if (env["PLUGIN_EXCLUDE"]) {
+  flags.push(`--exclude=${env["PLUGIN_EXCLUDE"]}`);
+}
+
+if (env["PLUGIN_INCLUDE"]) {
+  flags.push(`--include=${env["PLUGIN_INCLUDE"]}`);
+}
+
+if (env["PLUGIN_IMPORT_MAP"]) {
+  flags.push(`--import-map=${env["PLUGIN_IMPORT_MAP"]}`);
+}
+
+if (env["PLUGIN_NO_STATIC"]) {
+  flags.push(`--no-static`);
+}
+
+if (env["PLUGIN_PROD"]) {
+  flags.push(`--prod`);
+}
+
+if (env["PLUGIN_DRY_RUN"]) {
+  flags.push(`--dry-run`);
+}
+
+console.log("Deploying to Deno Deploy......");
+
+const prog = Deno.run({
+  cmd: [
+    "deployctl",
+    "deploy",
+    ...flags,
+    env["PLUGIN_ENTRYPOINT"],
+  ],
+  stdout: "piped",
+  stderr: "piped",
+});
+
+const [status, stdout, stderr] = await Promise.all([
+  prog.status(),
+  prog.output(),
+  prog.stderrOutput(),
+]);
+prog.close();
+
+const std = new TextDecoder().decode(stdout);
+const err = new TextDecoder().decode(stderr);
+
+console.log(std);
+
+if (!status.success) {
+  console.error("Deno Deploy failed!")
+  console.log(err);
+  Deno.exit(1);
+}
