DEV Community

Alex Spinov
Alex Spinov

Posted on

Deno 2 Has a Free API: Node.js Compatibility, npm Packages, and TypeScript Without Config

Deno 2 is a major release that brings full Node.js/npm compatibility while keeping Deno's security, built-in TypeScript, and developer experience. Run npm packages, use Node.js APIs, and deploy anywhere.

Why Deno 2?

  • Node.js compatible — run most npm packages without changes
  • TypeScript built-in — no tsconfig, no build step
  • Secure by default — explicit permissions for file, network, env
  • npm supportnpm: specifier, node_modules optional
  • Built-in tools — formatter, linter, test runner, benchmarker

Install

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

# Or
brew install deno
Enter fullscreen mode Exit fullscreen mode

Node.js Compatibility

// Use npm packages directly!
import express from 'npm:express@4';
import pg from 'npm:pg';
import chalk from 'npm:chalk';

const app = express();

app.get('/', (req, res) => {
  res.json({ message: chalk.green('Hello from Deno 2!') });
});

app.listen(3000, () => console.log('Server running'));
Enter fullscreen mode Exit fullscreen mode
# Run with network permission
deno run --allow-net server.ts

# Or allow all (development)
deno run -A server.ts
Enter fullscreen mode Exit fullscreen mode

Built-in HTTP Server

// Deno native API — simpler than Express
Deno.serve({ port: 3000 }, async (req) => {
  const url = new URL(req.url);

  if (url.pathname === '/api/users' && req.method === 'GET') {
    return Response.json([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
    ]);
  }

  if (url.pathname === '/api/users' && req.method === 'POST') {
    const body = await req.json();
    return Response.json({ id: 3, ...body }, { status: 201 });
  }

  return new Response('Not Found', { status: 404 });
});
Enter fullscreen mode Exit fullscreen mode

Built-in Tools

# Format code (like Prettier)
deno fmt

# Lint (like ESLint)
deno lint

# Test
deno test

# Benchmark
deno bench

# Type check
deno check main.ts

# Compile to single binary
deno compile --output myapp main.ts

# Generate docs
deno doc main.ts
Enter fullscreen mode Exit fullscreen mode

Testing (Built-in)

// users_test.ts
import { assertEquals } from 'jsr:@std/assert';

Deno.test('add user', async () => {
  const response = await fetch('http://localhost:3000/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ name: 'Alice' }),
  });
  const user = await response.json();
  assertEquals(user.name, 'Alice');
  assertEquals(response.status, 201);
});
Enter fullscreen mode Exit fullscreen mode
deno test --allow-net
Enter fullscreen mode Exit fullscreen mode

KV (Built-in Key-Value Database)

const kv = await Deno.openKv();

// Set
await kv.set(['users', 'alice'], { name: 'Alice', email: 'alice@example.com' });

// Get
const entry = await kv.get(['users', 'alice']);
console.log(entry.value); // { name: 'Alice', email: 'alice@example.com' }

// List
const iter = kv.list({ prefix: ['users'] });
for await (const entry of iter) {
  console.log(entry.key, entry.value);
}

// Atomic transactions
await kv.atomic()
  .set(['users', 'bob'], { name: 'Bob' })
  .set(['user_count'], new Deno.KvU64(2n))
  .commit();
Enter fullscreen mode Exit fullscreen mode

Permissions (Security)

# Granular permissions
deno run --allow-net=api.example.com --allow-read=./data --allow-env=API_KEY main.ts

# Permission prompt (interactive)
deno run main.ts
# ┌ ⚠️  Deno requests net access to "api.example.com"
# ├ Allow? [y/n/A]
Enter fullscreen mode Exit fullscreen mode

Key Features

Feature Details
npm support Full compatibility via npm:
TypeScript Built-in, zero config
Security Explicit permissions
Tools fmt, lint, test, bench, doc, compile
KV Built-in key-value database
Deploy Deno Deploy, Docker, any platform

Resources


Building with Deno? Check my Apify actors or email spinov001@gmail.com.

Top comments (0)