Use Cases (Mis à jour: 02/06/2026)

Deno TypeScript avec Claude Code : permissions, deno.json et Deno.serve

Guide pratique Deno avec Claude Code : permissions minimales, tâches deno.json, Deno.serve et fmt/lint/test avec code copiable.

Deno TypeScript avec Claude Code : permissions, deno.json et Deno.serve

Commencer par les permissions Deno

Deno est un runtime pour JavaScript et TypeScript, c’est-à-dire l’environnement qui exécute votre code. Son point fort pour un projet Claude Code est simple : Deno est sécurisé par défaut. L’accès aux fichiers, au réseau, aux variables d’environnement et aux processus externes doit être autorisé explicitement. La référence officielle est Security and permissions.

Claude Code peut générer un serveur, les tests, deno.json et une checklist de revue. Mais une demande vague produit souvent -A, des habitudes Node.js ou des dépendances inutiles. Il faut donc préciser l’API à utiliser, ce qui est interdit, les permissions exactes et la commande de vérification.

Quelques termes : une permission est une autorisation d’accès, deno task est une commande nommée dans deno.json, le formatter met le code en forme, le linter repère les risques, et le test runner exécute Deno.test(). Deno fournit ces outils. Pour compléter, voyez développement API, stratégies de test et conseils TypeScript.

Prompt utile pour Claude Code

Crée une petite API JSON avec Deno. Utilise Deno.serve, pas Express. Ajoute un deno.json avec les tâches dev, start, fmt, lint, test et check. N’utilise pas -A. Autorise seulement --allow-net=127.0.0.1:8000, --allow-read=./data et --allow-write=./data. Écris les tests avec Deno.test().

Ce prompt suit les pages officielles configuration, deno task, Deno.serve et deno test.

deno.json pour figer les commandes

{
  "tasks": {
    "dev": "deno run --watch --allow-net=127.0.0.1:8000 --allow-read=./data --allow-write=./data server.ts",
    "start": "deno run --allow-net=127.0.0.1:8000 --allow-read=./data --allow-write=./data server.ts",
    "fmt": "deno fmt",
    "lint": "deno lint",
    "test": "deno test",
    "check": "deno fmt --check && deno lint && deno test"
  },
  "fmt": {
    "lineWidth": 100,
    "semiColons": true
  },
  "lint": {
    "rules": {
      "tags": ["recommended"]
    }
  },
  "imports": {
    "@std/assert": "jsr:@std/assert"
  }
}

check devient la commande commune pour Claude Code, la revue locale et CI.

Exemple Deno.serve à copier

// app.ts
export type Item = {
  id: string;
  title: string;
  done: boolean;
};

export interface ItemStore {
  list(): Promise<Item[]>;
  save(items: Item[]): Promise<void>;
}

export class FileItemStore implements ItemStore {
  constructor(private readonly path = "./data/items.json") {}

  async list(): Promise<Item[]> {
    try {
      const text = await Deno.readTextFile(this.path);
      return JSON.parse(text) as Item[];
    } catch (error) {
      if (error instanceof Deno.errors.NotFound) {
        return [];
      }
      throw error;
    }
  }

  async save(items: Item[]): Promise<void> {
    await Deno.writeTextFile(this.path, JSON.stringify(items, null, 2));
  }
}

export function createHandler(store: ItemStore): (request: Request) => Promise<Response> {
  return async (request: Request): Promise<Response> => {
    const url = new URL(request.url);

    if (url.pathname === "/health") {
      return Response.json({ ok: true });
    }

    if (url.pathname === "/api/items" && request.method === "GET") {
      return Response.json(await store.list());
    }

    if (url.pathname === "/api/items" && request.method === "POST") {
      const body = await request.json().catch(() => null) as { title?: unknown } | null;

      if (!body || typeof body.title !== "string" || body.title.trim() === "") {
        return Response.json({ error: "title is required" }, { status: 400 });
      }

      const items = await store.list();
      const item: Item = {
        id: crypto.randomUUID(),
        title: body.title.trim(),
        done: false
      };

      await store.save([...items, item]);
      return Response.json(item, { status: 201 });
    }

    return new Response("Not Found", { status: 404 });
  };
}
// server.ts
import { createHandler, FileItemStore } from "./app.ts";

Deno.serve(
  { hostname: "127.0.0.1", port: 8000 },
  createHandler(new FileItemStore())
);
mkdir -p data
printf "[]\n" > data/items.json
deno task dev
curl http://127.0.0.1:8000/health
curl -X POST http://127.0.0.1:8000/api/items \
  -H "content-type: application/json" \
  -d '{"title":"Deno article draft"}'
curl http://127.0.0.1:8000/api/items

Tests sans permissions supplémentaires

// app_test.ts
import { assertEquals } from "@std/assert";
import { createHandler, type Item, type ItemStore } from "./app.ts";

class MemoryStore implements ItemStore {
  private items: Item[] = [];

  async list(): Promise<Item[]> {
    return [...this.items];
  }

  async save(items: Item[]): Promise<void> {
    this.items = [...items];
  }
}

Deno.test("GET /health returns ok", async () => {
  const handler = createHandler(new MemoryStore());
  const response = await handler(new Request("http://localhost/health"));

  assertEquals(response.status, 200);
  assertEquals(await response.json(), { ok: true });
});

Deno.test("POST /api/items creates an item", async () => {
  const handler = createHandler(new MemoryStore());
  const response = await handler(
    new Request("http://localhost/api/items", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ title: "Write article" })
    })
  );

  const created = await response.json() as Item;

  assertEquals(response.status, 201);
  assertEquals(created.title, "Write article");
  assertEquals(created.done, false);
});

Deno.test("POST /api/items rejects an empty title", async () => {
  const handler = createHandler(new MemoryStore());
  const response = await handler(
    new Request("http://localhost/api/items", {
      method: "POST",
      headers: { "content-type": "application/json" },
      body: JSON.stringify({ title: "" })
    })
  );

  assertEquals(response.status, 400);
});

Cas d’usage concrets

Premier cas : une petite API interne pour un outil d’administration, un test de webhook ou une démo JSON. Deno.serve suffit avant de choisir un framework plus lourd.

Deuxième cas : automatiser un dépôt. Validation de contenu, contrôle de configuration et snapshots d’API peuvent vivre dans deno task.

Troisième cas : former une équipe. Les erreurs de permissions rendent visibles les accès réseau, lecture et écriture.

Quatrième cas : un petit service HTTP destiné à rester proche des standards Web Request et Response.

Pièges fréquents

Ne laissez pas -A dans les tâches. Cela ouvre toutes les permissions et annule l’intérêt principal de Deno.

N’ajoutez pas Express, Jest, Prettier et ESLint avant d’avoir testé les outils intégrés.

N’oubliez pas de créer data/items.json; sinon l’exemple fichier échoue.

Ne faites pas toucher de vrais fichiers ou sockets à tous les tests. Gardez les unit tests en mémoire.

Ne copiez pas d’anciens exemples sans vérifier la documentation officielle.

CTA et vérification

Si ce flux devient régulier, documentez les commandes et permissions dans CLAUDE.md. Commencez avec le cheatsheet gratuit, utilisez les templates pour des prompts réutilisables, et passez par training and consultation pour une adoption d’équipe.

Vérification pratique : créez data/items.json, lancez deno task dev, ajoutez un item avec curl, puis exécutez deno task check. En revue, cherchez d’abord -A, les chemins trop larges et les tests unitaires qui demandent des permissions inutiles.

#Claude Code #Deno #TypeScript #runtime #security
Gratuit

PDF gratuit: cheatsheet Claude Code

Saisissez votre email et téléchargez une page avec commandes, habitudes de review et workflow sûr.

Nous protégeons vos données et n'envoyons pas de spam.

Masa

À propos de l'auteur

Masa

Ingénieur spécialisé dans les workflows pratiques avec Claude Code.