Written by: ekwoster.dev on Thu Jul 31

Building Modern Web Apps with Deno: A Beginner's Guide

Building Modern Web Apps with Deno: A Beginner's Guide

Cover image for Building Modern Web Apps with Deno: A Beginner's Guide

Building Modern Web Apps with Deno: A Beginner's Guide

In the rapidly evolving world of backend development, Deno is an exciting new runtime that promises a fresh, secure, and efficient way to build modern web applications. Created by Ryan Dahl, the original creator of Node.js, Deno addresses some of the design decisions and pain points of Node. In this article, we’ll explore what Deno is, its key features, how it compares to Node.js, and how you can get started building web applications with Deno.

What is Deno?

Deno is a modern runtime for JavaScript and TypeScript, built on the V8 JavaScript engine and Rust programming language. Its main goal is to provide a secure, productive, and reliable platform for server-side JavaScript.

Deno is designed with a few core principles:

  • Secure by default
  • Supports TypeScript out of the box
  • Ships as a single executable
  • Has a standard library
  • Includes a package manager-less approach

Why Deno Over Node?

Node.js has been around for over a decade and has a huge ecosystem. However, over the years, some core issues became apparent:

  • No built-in TypeScript support
  • Security vulnerabilities (Node scripts have unrestricted file and network access by default)
  • Complicated module resolution with node_modules
  • Legacy APIs and inconsistencies

Deno addresses many of these issues:

FeatureNode.jsDeno
TypeScriptRequires manual setupBuilt-in
SecurityNo sandboxing, full file/net accessRequires explicit permissions
Modulesnode_modules, NPMURL imports, no centralized registry
ExecutableMultiple dependenciesSingle binary

Setting Up Deno

To get started with Deno, you can install it via deno.land:

macOS / Linux (using Shell):

curl -fsSL https://deno.land/install.sh | sh

Windows (using PowerShell):

iwr https://deno.land/install.ps1 -useb | iex

Verify the installation:

deno --version

Creating a Simple Web Server with Deno

Let’s create a basic HTTP server using Deno.

Step 1: Create a file named server.ts

import { serve } from "https://deno.land/[email protected]/http/server.ts";

const handler = (request: Request): Response => {
  return new Response("Hello from Deno!", {
    headers: { "content-type": "text/plain" },
  });
};

console.log("Server running on http://localhost:8000");
await serve(handler, { port: 8000 });

Step 2: Run the server

deno run --allow-net server.ts

Note: --allow-net is required to enable network access for the application because Deno is secure by default.

Visit http://localhost:8000 in your browser, and you should see "Hello from Deno!"

Building a REST API with Deno and Oak

To create real-world applications, Deno has a growing ecosystem of third-party modules. One popular middleware framework is Oak—a middleware framework inspired by Koa (Node.js).

Step 1: Project Structure

my-deno-api/
├── controllers/
│   └── user.ts
├── routes/
│   └── user.ts
├── app.ts
└── deps.ts

Step 2: Dependency management - deps.ts

export { Application, Router } from "https://deno.land/x/oak/mod.ts";

Step 3: Create a simple controller - controllers/user.ts

import { Context } from "https://deno.land/x/oak/mod.ts";

export const getUser = (context: Context) => {
  context.response.body = { id: 1, name: "John Doe" };
};

Step 4: Define routes - routes/user.ts

import { Router } from "../deps.ts";
import { getUser } from "../controllers/user.ts";

const router = new Router();

router
  .get("/users/:id", getUser);

export default router;

Step 5: Initialize app - app.ts

import { Application } from "./deps.ts";
import userRoutes from "./routes/user.ts";

const app = new Application();

app.use(userRoutes.routes());
app.use(userRoutes.allowedMethods());

console.log("Server running on http://localhost:8000");
await app.listen({ port: 8000 });

Step 6: Run the application

deno run --allow-net app.ts

Try accessing http://localhost:8000/users/1 — You should get a JSON response.

Deno vs Node: Importing Modules

Deno moves away from NPM and node_modules. It uses direct URL imports:

import { serve } from "https://deno.land/std/http/server.ts";

While this may feel unusual at first, it simplifies dependency management. You can cache modules locally with Deno and even use a deps.ts file to centralize and version dependencies.

Permissions & Security

Deno uses explicit permissions for file, network, and environment access. Here are some common flags:

  • --allow-net: Allow network access
  • --allow-read: Allow file read access
  • --allow-write: Allow file write access
  • --allow-env: Allow access to environment variables
  • --allow-all: Allow all permissions

You can also restrict permissions further:

deno run --allow-net=api.foo.com app.ts

Deno Deploy: Seamless Hosting

Deno Deploy is an edge platform where you can deploy your Deno apps globally. It offers fast startup, scalability, and a seamless DX (Developer Experience). To get started, visit deno.com/deploy and connect your GitHub repo.

You can deploy apps using:

deno deploy

Ecosystem and Tooling

Deno has slowly but steadily built a solid ecosystem:

  • Standard library: https://deno.land/std
  • Third-party modules: https://deno.land/x
  • VSCode extension for debugging and IntelliSense
  • Built-in testing capabilities

Example Test File - hello_test.ts

import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

function add(a: number, b: number): number {
  return a + b;
}

deno.test("add two numbers", () => {
  assertEquals(add(2, 3), 5);
});

Run via:

deno test

Challenges and Considerations

  • Smaller ecosystem compared to Node.js
  • Some compatibility issues with existing JavaScript packages
  • Not all NPM packages work without wrappers (yet)

However, with the introduction of NPM compatibility layers via npm: imports and the growing interest from the developer community, many of these challenges are being addressed.

Conclusion

Deno is a breath of fresh air in the JavaScript server-side ecosystem. With built-in TypeScript, a secure-by-default runtime, and modern tooling, it’s an excellent choice for building secure and simple web applications. While it still has a smaller ecosystem, it’s rapidly growing and worth exploring, especially for new projects or those looking to adopt modern development patterns.

Whether you’re building a REST API, serverless function, or an entire backend system, Deno offers a reliable and forward-thinking foundation. Dive in, start experimenting, and consider using Deno for your next web development project.

Happy coding! ✨

⚡️ If you need this done – we offer such services: https://ekwoster.dev/service/api-development