DEV Community

Alex Spinov
Alex Spinov

Posted on

Deno 2 Has a Free API You're Not Using

Deno 2 shipped with full npm compatibility, but the real story is the built-in APIs that eliminate entire categories of dependencies. No bundler, no test runner, no formatter to install.

The Free APIs You're Missing

1. Deno.serve() — Zero-Config HTTP Server

Deno.serve({ port: 3000 }, async (req) => {
  const url = new URL(req.url);

  if (url.pathname === "/api/users" && req.method === "GET") {
    const users = await Deno.readTextFile("./data/users.json");
    return Response.json(JSON.parse(users));
  }

  if (url.pathname === "/api/upload" && req.method === "POST") {
    const form = await req.formData();
    const file = form.get("file") as File;
    await Deno.writeFile(`./uploads/${file.name}`, file.stream());
    return Response.json({ ok: true });
  }

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

HTTP/2 server with streaming, WebSocket support, and zero imports.

2. Deno.Kv — Built-In Key-Value Database

const kv = await Deno.openKv();

// Set
await kv.set(["users", "user-123"], { name: "Alice", role: "admin" });

// Get
const user = await kv.get(["users", "user-123"]);
console.log(user.value); // { name: "Alice", role: "admin" }

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

// Atomic transactions
await kv.atomic()
  .check({ key: ["users", "user-123"], versionstamp: user.versionstamp })
  .set(["users", "user-123"], { ...user.value, role: "superadmin" })
  .commit();
Enter fullscreen mode Exit fullscreen mode

SQLite-backed KV store with ACID transactions. Zero setup, works locally and on Deno Deploy.

3. deno test — Built-In Test Runner

import { assertEquals, assertRejects } from "jsr:@std/assert";

Deno.test("fetch users returns array", async () => {
  const resp = await fetch("http://localhost:3000/api/users");
  const data = await resp.json();
  assertEquals(Array.isArray(data), true);
});

Deno.test({
  name: "database operations",
  permissions: { read: true, write: true },
  fn: async () => {
    const kv = await Deno.openKv(":memory:");
    await kv.set(["test"], "value");
    const result = await kv.get(["test"]);
    assertEquals(result.value, "value");
  },
});
Enter fullscreen mode Exit fullscreen mode

Test runner with permissions, sanitizers, and coverage — built in.

4. Deno.cron() — Built-In Cron Jobs

Deno.cron("daily-report", "0 9 * * *", async () => {
  const data = await generateReport();
  await sendEmail(data);
});

Deno.cron("cleanup", "*/30 * * * *", async () => {
  const kv = await Deno.openKv();
  // Clean expired entries
});
Enter fullscreen mode Exit fullscreen mode

5. Web Standard APIs — No Polyfills

// Streams
const file = await Deno.open("large.csv");
const stream = file.readable
  .pipeThrough(new TextDecoderStream())
  .pipeThrough(new TransformStream({
    transform(chunk, controller) {
      controller.enqueue(chunk.toUpperCase());
    }
  }));

// BroadcastChannel
const channel = new BroadcastChannel("updates");
channel.onmessage = (e) => console.log(e.data);
Enter fullscreen mode Exit fullscreen mode

Getting Started

curl -fsSL https://deno.land/install.sh | sh
deno init my-project
deno task dev
Enter fullscreen mode Exit fullscreen mode

Need data from any website delivered as clean JSON? I build production web scrapers that handle anti-bot, proxies, and rate limits. 77 scrapers running in production. Email me: Spinov001@gmail.com

Check out my awesome-web-scraping list for the best scraping tools and resources.

Top comments (0)