Deno 2.0 dropped with Node.js compatibility at the top of the feature list. Ryan Dahl's "fixed Node.js" is finally pragmatic enough to use in real projects.
The original Deno was ambitious but incompatible with Node.js ecosystem. Deno 2.0 changed the calculation:
// Deno 2.0 runs most Node.js code
import express from 'npm:express@4';
const app = express();
app.get('/', (req, res) => res.send('Hello from Deno!'));
app.listen(3000);npm: imports work. Most Node packages work. This was the missing piece.
// deno.json (replaces package.json)
{
"imports": {
"express": "npm:express@4",
"@/": "./src/"
},
"tasks": {
"dev": "deno run --watch main.ts",
"start": "deno run main.ts"
}
}No node_modules. Dependencies cached globally. Clean.
# Node.js: full system access always
node server.js
# Deno: explicit permissions required
deno run --allow-net --allow-read server.ts
# Anything not listed is blocked# Deno runs TypeScript natively, zero config
deno run my-file.tsNo ts-node. No tsconfig tweaking. Just works.
deno fmt # Format code (like Prettier)
deno lint # Lint code
deno test # Run tests
deno check # Type check
deno compile # Single binary outputOne tool. No tool chain configuration.
Deno 2.0 is genuinely good now. For new projects, especially TypeScript-heavy ones: it's worth trying.
The reasons to choose Node over Deno are shrinking. The ecosystem compatibility story is mostly solved. The developer experience is actually better.
# Try it today
curl -fsSL https://deno.land/install.sh | sh
deno run https://deno.land/std/examples/welcome.ts