Node.js requires package.json, node_modules, tsconfig.json, a bundler, a linter, a formatter, and a test runner. That's 6 tools before you write a single line of business logic.
What if your runtime handled all of that natively?
Deno 2 ships TypeScript support, a package manager, linter, formatter, test runner, and benchmarking tool — all built in. And now it's fully compatible with Node.js and npm.
What Changed in Deno 2
The biggest shift: backward compatibility with Node.js. Deno 2 can:
- Import from
npm:directly —import express from "npm:express" - Read
package.jsonand usenode_modulesif present - Run most Node.js projects without modifications
- Use CommonJS modules alongside ESM
This means you can migrate incrementally — no rewrite required.
Quick Start
curl -fsSL https://deno.land/install.sh | sh
deno init my-project
cd my-project && deno task dev
Native TypeScript — Zero Configuration
// main.ts — just run it: deno run main.ts
interface User {
id: number;
name: string;
email: string;
}
const users: User[] = [];
Deno.serve({ port: 8000 }, async (req: Request): Promise<Response> => {
const url = new URL(req.url);
if (url.pathname === "/users" && req.method === "GET") {
return Response.json(users);
}
if (url.pathname === "/users" && req.method === "POST") {
const body: Omit<User, "id"> = await req.json();
const user = { ...body, id: users.length + 1 };
users.push(user);
return Response.json(user, { status: 201 });
}
return new Response("Not Found", { status: 404 });
});
No tsconfig.json. No ts-node. No build step. Just deno run --allow-net main.ts.
Built-in Tools Replace Your Toolchain
# Linter (replaces ESLint)
deno lint
# Formatter (replaces Prettier)
deno fmt
# Test runner (replaces Jest/Vitest)
deno test
# Benchmarking (replaces custom bench scripts)
deno bench
# Type checking
deno check main.ts
# Compile to standalone binary
deno compile --output myapp main.ts
One tool. One command. No configuration files.
npm Compatibility
// Use npm packages directly — no install step
import express from "npm:express@4";
import { PrismaClient } from "npm:@prisma/client";
import chalk from "npm:chalk@5";
const app = express();
const prisma = new PrismaClient();
app.get("/users", async (req, res) => {
const users = await prisma.user.findMany();
console.log(chalk.green(`Found ${users.length} users`));
res.json(users);
});
app.listen(3000);
Security by Default
# Explicit permissions — no surprise network access
deno run --allow-net=api.example.com --allow-read=./data main.ts
# Or grant all (for trusted code)
deno run -A main.ts
A compromised npm package can't access your filesystem or network unless you explicitly grant it.
Deno 2 vs Node.js vs Bun
| Feature | Deno 2 | Node.js | Bun |
|---|---|---|---|
| TypeScript | Native | Needs ts-node/tsx | Native |
| Package manager | Built-in | npm/pnpm/yarn | Built-in |
| Linter | Built-in | ESLint | None |
| Formatter | Built-in | Prettier | None |
| Test runner | Built-in | Jest/Vitest | Built-in |
| npm compatibility | Full | Native | Full |
| Security model | Permission-based | Open access | Open access |
| Compile to binary | Yes | Experimental | Yes |
When to Choose Deno 2
Choose Deno when:
- You want fewer config files and tools to manage
- Security matters — you want sandboxed execution
- TypeScript-first development without setup
- Deploying to edge (Deno Deploy, Cloudflare Workers)
Skip Deno when:
- You rely on Node.js-specific APIs with no Deno equivalent (rare now)
- Your team doesn't want to learn new CLI commands
- You need maximum raw startup speed (Bun is faster)
The Bottom Line
Deno 2 is what Node.js would look like if designed today. Full npm compatibility removes the last barrier to adoption.
Start here: deno.land
Need custom data extraction, scraping, or automation? I build tools that collect and process data at scale — 78 actors on Apify Store and 265+ open-source repos. Email me: Spinov001@gmail.com | My Apify Actors
Top comments (0)