diff --git a/scripts/coder-dev.sh b/scripts/coder-dev.sh
index d379e226b6f3b..dbba6b8819029 100755
--- a/scripts/coder-dev.sh
+++ b/scripts/coder-dev.sh
@@ -10,6 +10,7 @@ source "${SCRIPT_DIR}/lib.sh"
 
 GOOS="$(go env GOOS)"
 GOARCH="$(go env GOARCH)"
+DEBUG_DELVE="${DEBUG_DELVE:-0}"
 BINARY_TYPE=coder-slim
 if [[ ${1:-} == server ]]; then
 	BINARY_TYPE=coder
@@ -55,4 +56,10 @@ coder)
 	;;
 esac
 
-exec "${CODER_DEV_BIN}" --global-config "${CODER_DEV_DIR}" "$@"
+runcmd=("${CODER_DEV_BIN}")
+if [[ "${DEBUG_DELVE}" == 1 ]]; then
+	set -x
+	runcmd=(dlv debug --headless --continue --listen 127.0.0.1:12345 --accept-multiclient ./cmd/coder --)
+fi
+
+CGO_ENABLED=0 exec "${runcmd[@]}" --global-config "${CODER_DEV_DIR}" "$@"
diff --git a/scripts/develop.sh b/scripts/develop.sh
index ba5116f5a7735..00d96389e21fd 100755
--- a/scripts/develop.sh
+++ b/scripts/develop.sh
@@ -14,11 +14,12 @@ source "${SCRIPT_DIR}/lib.sh"
 set -euo pipefail
 
 CODER_DEV_ACCESS_URL="${CODER_DEV_ACCESS_URL:-http://127.0.0.1:3000}"
+debug=0
 DEFAULT_PASSWORD="SomeSecurePassword!"
 password="${CODER_DEV_ADMIN_PASSWORD:-${DEFAULT_PASSWORD}}"
 use_proxy=0
 
-args="$(getopt -o "" -l access-url:,use-proxy,agpl,password: -- "$@")"
+args="$(getopt -o "" -l access-url:,use-proxy,agpl,debug,password: -- "$@")"
 eval set -- "$args"
 while true; do
 	case "$1" in
@@ -38,6 +39,10 @@ while true; do
 		use_proxy=1
 		shift
 		;;
+	--debug)
+		debug=1
+		shift
+		;;
 	--)
 		shift
 		break
@@ -136,7 +141,7 @@ fatal() {
 	trap 'fatal "Script encountered an error"' ERR
 
 	cdroot
-	start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@"
+	DEBUG_DELVE="${debug}" start_cmd API "" "${CODER_DEV_SHIM}" server --http-address 0.0.0.0:3000 --swagger-enable --access-url "${CODER_DEV_ACCESS_URL}" --dangerous-allow-cors-requests=true "$@"
 
 	echo '== Waiting for Coder to become ready'
 	# Start the timeout in the background so interrupting this script