Introduction to Deno
By Flavio Copes
Get started with Deno, the secure JavaScript and TypeScript runtime, including permissions, Deno.serve, npm and JSR packages, tasks, tests, and built-in tools.
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 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 fmtdeno lintdeno testdeno benchdeno 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:
curl -fsSL https://deno.land/install.sh | sh
On macOS you can also use Homebrew:
brew install deno
On Windows PowerShell:
irm https://deno.land/install.ps1 | iex
Verify the installation:
deno --version
The official installation guide lists package managers, Docker images, supported platforms, and manual downloads.
Create a Deno project
Create a small project with:
deno init my_project
cd my_project
This creates:
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:
deno main.ts
Run its tests:
deno test
Run TypeScript directly
Deno runs .ts files without a separate tsc command.
Create hello.ts:
const name: string = 'Roger'
console.log(`Hello ${name}`)
Run it:
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:
Deno.serve({ port: 8000 }, () => {
return new Response('Hello from Deno')
})
Run it with network permission:
deno run --allow-net server.ts
You can use the shorter permission flag:
deno -N server.ts
Then open http://localhost:8000/.
The Deno HTTP server guide 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-netfor network access--allow-readfor reading files--allow-writefor writing files--allow-envfor environment variables--allow-runfor subprocesses--allow-sysfor operating-system information--allow-ffifor native libraries
You can restrict a permission to specific resources:
deno run --allow-read=./data app.ts
This allows reads inside ./data, not the entire filesystem.
-A or --allow-all grants all permissions:
deno run -A app.ts
Use it only when the program really needs unrestricted access and you trust its dependencies.
The official permissions documentation explains the permission model and its limits.
Add packages from JSR
JSR is the modern JavaScript registry recommended by Deno. The Deno Standard Library is published there.
Install the assertion package:
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:
import { assertEquals } from '@std/assert'
assertEquals(1 + 1, 2)
You can also use a full JSR specifier directly:
import { join } from 'jsr:@std/path'
Use npm packages
Deno can install and run npm packages:
deno install express
You can also use an explicit npm: specifier:
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 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 explains local modules, jsr:, npm:, URL imports, and import maps.
Use deno.json
Here is a small configuration:
{
"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:
deno task dev
Deno can also run scripts from an existing package.json with deno task.
See the official configuration guide for all deno.json options.
Format, lint, and test
Format the project:
deno fmt
Check the code for common problems:
deno lint
Run tests:
deno test
Watch tests and run them again after changes:
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:
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.
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.
Related posts about js: