diff --git a/cli/plug_run.ts b/cli/plug_run.ts
index 1de49fc..d7d2003 100644
--- a/cli/plug_run.ts
+++ b/cli/plug_run.ts
@@ -7,6 +7,7 @@ import { ServerSystem } from "../server/server_system.ts";
 import { AssetBundlePlugSpacePrimitives } from "../common/spaces/asset_bundle_space_primitives.ts";
 import { determineDatabaseBackend } from "../server/db_backend.ts";
 import { EndpointHook } from "../plugos/hooks/endpoint.ts";
+import { determineShellBackend } from "../server/shell_backend.ts";
 
 export async function runPlug(
   spacePath: string,
@@ -34,6 +35,7 @@ export async function runPlug(
       builtinAssetBundle,
     ),
     dbBackend,
+    determineShellBackend(spacePath),
   );
   await serverSystem.init(true);
   app.use((context, next) => {
diff --git a/plugos/syscalls/shell.deno.ts b/plugos/syscalls/shell.deno.ts
deleted file mode 100644
index e2fc468..0000000
--- a/plugos/syscalls/shell.deno.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { ShellResponse } from "../../server/rpc.ts";
-import type { SysCallMapping } from "../system.ts";
-
-export function shellSyscalls(cwd: string): SysCallMapping {
-  return {
-    "shell.run": async (
-      _ctx,
-      cmd: string,
-      args: string[],
-    ): Promise<ShellResponse> => {
-      const p = new Deno.Command(cmd, {
-        args: args,
-        cwd,
-        stdout: "piped",
-        stderr: "piped",
-      });
-      const output = await p.output();
-      const stdout = new TextDecoder().decode(output.stdout);
-      const stderr = new TextDecoder().decode(output.stderr);
-
-      return { stdout, stderr, code: output.code };
-    },
-  };
-}
diff --git a/server/instance.ts b/server/instance.ts
index c73f75f..8b0bdbb 100644
--- a/server/instance.ts
+++ b/server/instance.ts
@@ -87,6 +87,7 @@ export class SpaceServer {
       const serverSystem = new ServerSystem(
         this.spacePrimitives,
         this.kvPrimitives,
+        this.shellBackend,
       );
       this.serverSystem = serverSystem;
     }
diff --git a/server/server_system.ts b/server/server_system.ts
index eee226f..14c0f69 100644
--- a/server/server_system.ts
+++ b/server/server_system.ts
@@ -19,7 +19,7 @@ import { spaceSyscalls } from "./syscalls/space.ts";
 import { systemSyscalls } from "../web/syscalls/system.ts";
 import { yamlSyscalls } from "../common/syscalls/yaml.ts";
 import { sandboxFetchSyscalls } from "../plugos/syscalls/fetch.ts";
-import { shellSyscalls } from "../plugos/syscalls/shell.deno.ts";
+import { shellSyscalls } from "./syscalls/shell.ts";
 import { SpacePrimitives } from "../common/spaces/space_primitives.ts";
 import { base64EncodedDataUrl } from "../plugos/asset_bundle/base64.ts";
 import { Plug } from "../plugos/plug.ts";
@@ -32,6 +32,7 @@ import { codeWidgetSyscalls } from "../web/syscalls/code_widget.ts";
 import { CodeWidgetHook } from "../web/hooks/code_widget.ts";
 import { KVPrimitivesManifestCache } from "../plugos/manifest_cache.ts";
 import { KvPrimitives } from "../plugos/lib/kv_primitives.ts";
+import { ShellBackend } from "./shell_backend.ts";
 
 const fileListInterval = 30 * 1000; // 30s
 
@@ -47,6 +48,7 @@ export class ServerSystem {
   constructor(
     private baseSpacePrimitives: SpacePrimitives,
     readonly kvPrimitives: KvPrimitives,
+    private shellBackend: ShellBackend,
   ) {
   }
 
@@ -123,7 +125,7 @@ export class ServerSystem {
 
     this.system.registerSyscalls(
       ["shell"],
-      shellSyscalls("."),
+      shellSyscalls(this.shellBackend),
     );
 
     await this.loadPlugs();
diff --git a/server/syscalls/shell.ts b/server/syscalls/shell.ts
new file mode 100644
index 0000000..e504db1
--- /dev/null
+++ b/server/syscalls/shell.ts
@@ -0,0 +1,16 @@
+import { shell } from "$sb/syscalls.ts";
+import { SysCallMapping } from "../../plugos/system.ts";
+import { ShellResponse } from "../../server/rpc.ts";
+import { ShellBackend } from "../shell_backend.ts";
+
+export function shellSyscalls(shellBackend: ShellBackend): SysCallMapping {
+  return {
+    "shell.run": (
+      _ctx,
+      cmd: string,
+      args: string[],
+    ): Promise<ShellResponse> => {
+      return shellBackend.handle({ cmd, args });
+    },
+  };
+}