# Introduction to Deno

> Get started with Deno, the secure JavaScript and TypeScript runtime, including permissions, Deno.serve, npm and JSR packages, tasks, tests, and built-in tools.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2020-05-12 | Updated: 2026-07-18 | Topics: [JavaScript](https://flaviocopes.com/tags/js/) | Canonical: https://flaviocopes.com/deno/

Deno is a JavaScript, TypeScript, and WebAssembly runtime. It runs TypeScript directly, uses ES Modules, has secure defaults, supports npm packages, and includes a formatter, linter, test runner, and other development tools.

You can use Deno for servers, command-line programs, scripts, and existing Node.js projects.

The [official Deno introduction](https://docs.deno.com/runtime/) is updated alongside the runtime.

## Deno and Node.js

Deno was created by Ryan Dahl, who also created Node.js. The two runtimes share the V8 JavaScript engine, but they made different design choices.

Deno starts with a restrictive permission model. Code cannot read files, access environment variables, open network connections, or run subprocesses unless you allow it.

Deno also provides a complete toolchain:

- TypeScript support without a separate compilation command
- ES Modules
- npm and JSR package support
- `deno fmt`
- `deno lint`
- `deno test`
- `deno bench`
- `deno compile`

Modern Deno also supports `package.json`, `node_modules`, Node.js built-in modules, and many npm packages. The old description of Deno as a runtime with "no package manager" is no longer accurate.

## Install Deno

On macOS and Linux, the official install command is:

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

On macOS you can also use Homebrew:

```bash
brew install deno
```

On Windows PowerShell:

```powershell
irm https://deno.land/install.ps1 | iex
```

Verify the installation:

```bash
deno --version
```

The [official installation guide](https://docs.deno.com/runtime/getting_started/installation/) lists package managers, Docker images, supported platforms, and manual downloads.

## Create a Deno project

Create a small project with:

```bash
deno init my_project
cd my_project
```

This creates:

```text
my_project
├── deno.json
├── main.ts
└── main_test.ts
```

`deno.json` stores project configuration, tasks, imports, and formatter or linter settings.

Run the generated program:

```bash
deno main.ts
```

Run its tests:

```bash
deno test
```

## Run TypeScript directly

Deno runs `.ts` files without a separate `tsc` command.

Create `hello.ts`:

```ts
const name: string = 'Roger'

console.log(`Hello ${name}`)
```

Run it:

```bash
deno hello.ts
```

Deno removes TypeScript types before executing the program. It does not need a JavaScript build file for this example.

## Create an HTTP server

Deno has a built-in HTTP server API based on web-standard `Request` and `Response` objects.

Create `server.ts`:

```ts
Deno.serve({ port: 8000 }, () => {
  return new Response('Hello from Deno')
})
```

Run it with network permission:

```bash
deno run --allow-net server.ts
```

You can use the shorter permission flag:

```bash
deno -N server.ts
```

Then open <http://localhost:8000/>.

The [Deno HTTP server guide](https://docs.deno.com/runtime/fundamentals/http_server/) covers routing, request bodies, errors, TLS, and HTTP/2.

## Understand Deno permissions

The server needs `--allow-net` because Deno denies network access by default.

Common permissions include:

- `--allow-net` for network access
- `--allow-read` for reading files
- `--allow-write` for writing files
- `--allow-env` for environment variables
- `--allow-run` for subprocesses
- `--allow-sys` for operating-system information
- `--allow-ffi` for native libraries

You can restrict a permission to specific resources:

```bash
deno run --allow-read=./data app.ts
```

This allows reads inside `./data`, not the entire filesystem.

`-A` or `--allow-all` grants all permissions:

```bash
deno run -A app.ts
```

Use it only when the program really needs unrestricted access and you trust its dependencies.

The [official permissions documentation](https://docs.deno.com/runtime/fundamentals/security/) explains the permission model and its limits.

## Add packages from JSR

[JSR](https://jsr.io/) is the modern JavaScript registry recommended by Deno. The Deno Standard Library is published there.

Install the assertion package:

```bash
deno install jsr:@std/assert
```

Deno adds the dependency to the nearest `deno.json` or `package.json`.

You can now import it using the recorded name:

```ts
import { assertEquals } from '@std/assert'

assertEquals(1 + 1, 2)
```

You can also use a full JSR specifier directly:

```ts
import { join } from 'jsr:@std/path'
```

## Use npm packages

Deno can install and run npm packages:

```bash
deno install express
```

You can also use an explicit `npm:` specifier:

```ts
import express from 'npm:express'
```

Deno works with `package.json` and can run many existing Node.js projects without converting them to a Deno-specific layout.

Some packages expect a local `node_modules` folder. Deno can create one when needed, and `nodeModulesDir` in `deno.json` controls that behavior.

The [Deno dependency management guide](https://docs.deno.com/runtime/packages/) explains JSR, npm, `package.json`, lockfiles, workspaces, and lifecycle-script permissions.

## Import modules from URLs

Deno still supports full `https://` URL imports.

For application dependencies, prefer JSR or npm packages with explicit versions. Registry dependencies are easier to update, audit, and manage in a project configuration file.

The [Deno modules guide](https://docs.deno.com/runtime/fundamentals/modules/) explains local modules, `jsr:`, `npm:`, URL imports, and import maps.

## Use deno.json

Here is a small configuration:

```json
{
  "tasks": {
    "dev": "deno run --watch --allow-net server.ts",
    "start": "deno run --allow-net server.ts",
    "test": "deno test"
  },
  "fmt": {
    "semiColons": false,
    "singleQuote": true
  }
}
```

Run a task with:

```bash
deno task dev
```

Deno can also run scripts from an existing `package.json` with `deno task`.

See the [official configuration guide](https://docs.deno.com/runtime/fundamentals/configuration/) for all `deno.json` options.

## Format, lint, and test

Format the project:

```bash
deno fmt
```

Check the code for common problems:

```bash
deno lint
```

Run tests:

```bash
deno test
```

Watch tests and run them again after changes:

```bash
deno test --watch
```

These tools ship with Deno. You do not need separate formatter, linter, or test-runner dependencies for a basic project.

## Compile a program

`deno compile` creates a standalone executable:

```bash
deno compile --output hello hello.ts
```

The resulting program can run on a machine that does not have Deno installed.

Permissions used by the compiled program must be granted when compiling. Cross-compilation and other options are documented in the [official `deno compile` reference](https://docs.deno.com/runtime/reference/cli/compile/).

## Should you learn Deno?

Learn Deno if you want a TypeScript-first runtime with secure defaults and built-in tools.

You do not have to choose between the Deno and Node.js ecosystems. Deno's npm and Node.js compatibility means you can reuse many existing packages while adopting Deno one project at a time.
