Deno is a modern JavaScript and TypeScript runtime built on V8 and Rust. Created by Ryan Dahl (the original creator of Node.js), Deno addresses design decisions he regretted in Node.js: Deno has first-class TypeScript support with no build step required, uses ES modules exclusively (no CommonJS), has a secure-by-default permissions model (scripts cannot access the file system, network, or environment unless explicitly granted), and includes a standard library maintained by the Deno team. Deno also includes built-in tools: a formatter (deno fmt), linter (deno lint), test runner (deno test), and bundler (deno bundle). Deno 2.0 introduced Node.js compatibility mode, allowing many npm packages to run without modification. This guide covers installing Deno on RHEL 9 and building a simple HTTP server.
Prerequisites
- RHEL 9 with sudo/root access
Step 1 — Install Deno
# Install via the official installer script
curl -fsSL https://deno.land/install.sh | sh
# Add Deno to PATH
echo 'export DENO_INSTALL="$HOME/.deno"' >> ~/.bashrc
echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc
deno --version
Step 2 — Run a TypeScript Script (No Compilation Needed)
# hello.ts — Deno runs TypeScript natively, no tsc needed
const message: string = "Hello from Deno on RHEL 9!";
console.log(message);
const numbers: number[] = [1, 2, 3, 4, 5];
const sum = numbers.reduce((a, b) => a + b, 0);
console.log(`Sum: ${sum}`);
deno run hello.ts
Step 3 — Build an HTTP Server
# server.ts — Deno HTTP server using the built-in API
const port = parseInt(Deno.env.get("PORT") ?? "8000");
Deno.serve({ port }, (req: Request): Response => {
const url = new URL(req.url);
if (url.pathname === "/health") {
return Response.json({ status: "ok", runtime: "deno", version: Deno.version.deno });
}
if (url.pathname === "/api/items") {
const items = [
{ id: 1, name: "Widget" },
{ id: 2, name: "Gadget" },
];
return Response.json({ items, count: items.length });
}
return new Response("Not Found", { status: 404 });
});
console.log(`Server running on port ${port}`);
# Run with explicit permissions (Deno's security model)
deno run
--allow-net # Allow network access
--allow-env=PORT # Allow reading the PORT env variable
server.ts
# Test
curl http://localhost:8000/health
curl http://localhost:8000/api/items
Step 4 — Deploy as a systemd Service
# /etc/systemd/system/mydenoapp.service
[Unit]
Description=Deno HTTP Server
After=network.target
[Service]
User=denoapp
Group=denoapp
WorkingDirectory=/var/www/mydenoapp
ExecStart=/home/denoapp/.deno/bin/deno run
--allow-net
--allow-env=PORT
server.ts
Environment=PORT=8000
Restart=always
[Install]
WantedBy=multi-user.target
systemctl daemon-reload && systemctl enable --now mydenoapp
Step 5 — Built-in Tools
# Format code
deno fmt server.ts
# Lint code
deno lint server.ts
# Run tests
deno test --allow-net
# Bundle to single JavaScript file
deno bundle server.ts bundle.js
Conclusion
Deno on RHEL 9 provides a modern JavaScript/TypeScript runtime with built-in security, formatting, linting, and testing tools. Deno’s permission model is its most distinctive feature — scripts must explicitly request access to network, file system, and environment resources, making it impossible for malicious or compromised dependencies to silently exfiltrate data. For production deployments, Deno’s native TypeScript support eliminates the TypeScript compilation step required in Node.js workflows, simplifying CI/CD pipelines for TypeScript applications.
Next steps: How to Install Node.js on RHEL 9, How to Install Go on RHEL 9, and How to Install Nginx on RHEL 9.