DenoHost allows you to seamlessly run Deno scripts or
inline JavaScript/TypeScript code within your .NET applications.
It bundles platform-specific Deno executables as separate NuGet packages and
provides a simple, consistent API for execution.
- Modular runtime packages (per RID)
- Clean .NET API with async execution
- Testable with xUnit
- Packaged for NuGet (multi-target)
- Linux, Windows, macOS support
dotnet add package DenoHost.Core| Package | Description | Platforms |
|---|---|---|
DenoHost.Core |
Core execution logic (API) | all |
DenoHost.Runtime.win-x64 |
Bundled Deno for Windows | win-x64 |
DenoHost.Runtime.win-arm64 |
Bundled Deno for Windows ARM | win-arm64 |
DenoHost.Runtime.linux-x64 |
Deno for Linux | linux-x64 |
DenoHost.Runtime.linux-arm64 |
Deno for ARM Linux | linux-arm64 |
DenoHost.Runtime.osx-x64 |
Deno for macOS Intel | osx-x64 |
DenoHost.Runtime.osx-arm64 |
Deno for macOS Apple Silicon | osx-arm64 |
For simple script execution with immediate results:
using DenoHost.Core;
var options = new DenoExecuteBaseOptions { WorkingDirectory = "./scripts" };
string[] args = ["run", "app.ts"];
await Deno.Execute(options, args);You can cancel execution via a CancellationToken. Cancellation throws an OperationCanceledException and terminates the underlying Deno process.
using DenoHost.Core;
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var options = new DenoExecuteBaseOptions { WorkingDirectory = "./scripts" };
await Deno.Execute(options, ["run", "long-running.ts"], cts.Token);DenoHost passes arguments via ProcessStartInfo.ArgumentList. Pass each argument as its own string (avoid adding shell-style quotes inside argument strings).
await Deno.Execute("eval", ["console.log('hello world')"]);For long-running processes with interactive communication:
using DenoHost.Core;
// Create a managed Deno process
using var denoProcess = new DenoProcess(
command: "run",
args: ["--allow-read", "server.ts"],
workingDirectory: "./scripts"
);
// Start the process
await denoProcess.StartAsync();
// Send input to the process
await denoProcess.SendInputAsync("hello");
// Stop gracefully when done
await denoProcess.StopAsync();- .NET 9.0+
- Deno version is bundled per RID via GitHub Releases
- No need to install Deno globally
- Runtime packages verify downloaded Deno archives with SHA-256 before extraction.
- A SHA-256 checksum file is generated for the bundled executable and shipped with each runtime package.
- Runtime packages can additionally ship
deno.metadata.jsonanddeno.metadata.sig. DenoHost.Corerequires signed metadata verification (signature + binary hash) before process start.
- Signing key input for build/runtime packaging:
DENOHOST_METADATA_SIGNING_PRIVATE_KEY_PEM - Verification key is versioned in the repository as
Config/metadata-signing-public.pemand embedded intoDenoHost.Core. - Runtime signature verification uses the bundled public key only.
Release/package builds must provide DENOHOST_METADATA_SIGNING_PRIVATE_KEY_PEM; otherwise the workflow in .github/workflows/build.yml fails, and DenoHost.Runtime.Downloader.DownloaderLogic throws at runtime instead of silently skipping signing. The bundled verification key is Config/metadata-signing-public.pem, which is embedded into DenoHost.Core.
- Stable tags (
vX.Y.Z) are accepted only when a matching prerelease tag (vX.Y.Z-alpha.1) exists on the same commit. - Packaged smoke tests must pass before NuGet publish.
- Release publish is blocked if checksum bypass is enabled.
For incident mitigation only, checksum validation can be bypassed by setting:
DENOHOST_ALLOW_CHECKSUM_BYPASS=trueUse this only as a short-term emergency workaround. Keep it disabled in normal operation.
If you're using DenoHost in a real project, I'd love to hear about it.
This project is licensed under the MIT License.
See SECURITY.md for how to report vulnerabilities.