skills/denoland/skills/deno-project-templates

deno-project-templates

SKILL.md

Deno Project Templates

This skill provides templates for creating new Deno projects with modern best practices.

When to Use This Skill

  • Creating a new Deno project from scratch
  • Setting up project structure for different application types
  • Scaffolding Fresh web apps, CLI tools, libraries, or API servers

Scope Boundaries

This skill applies only when the user asks for a Deno project. Follow these rules:

  • If the user asks for a Node.js, Python, Go, Rust, or other non-Deno project, answer using that technology's project setup directly. Do not suggest Deno templates.
  • Only use these templates when the user explicitly asks for a Deno project or is working in a Deno environment.
  • When mentioning deprecated patterns, describe them generically. Do not write out deprecated URLs or import syntax — only show the correct modern approach.

Project Types

Choose the appropriate template based on what you want to build:

Type Use Case Key Files
Fresh web app Full-stack web application with Fresh framework main.ts, routes/, islands/
CLI tool Command-line application main.ts with arg parsing
Library Reusable package to publish on JSR mod.ts, mod_test.ts
API server Backend API without frontend main.ts with HTTP handlers

Fresh Web App

For full-stack web applications, use the Fresh initializer:

deno run -Ar jsr:@fresh/init my-project
cd my-project

This creates:

  • deno.json - Project configuration and dependencies
  • main.ts - Server entry point
  • client.ts - Client entry point (CSS imports)
  • vite.config.ts - Vite build configuration
  • routes/ - Pages and API routes (file-based routing)
  • islands/ - Interactive components that get JavaScript on the client
  • components/ - Server-only components (no JavaScript shipped)
  • static/ - Static assets like images, CSS

Development: Fresh uses Vite. The dev server runs at http://localhost:5173 (not port 8000).

deno task dev

CLI Tool

Create a command-line application with argument parsing.

Template files: See assets/cli-tool/ directory.

deno.json

{
  "name": "my-cli",
  "version": "0.1.0",
  "exports": "./main.ts",
  "tasks": {
    "dev": "deno run --allow-all main.ts",
    "compile": "deno compile --allow-all -o my-cli main.ts"
  },
  "imports": {
    "@std/cli": "jsr:@std/cli@^1",
    "@std/fmt": "jsr:@std/fmt@^1"
  }
}

main.ts

import { parseArgs } from "@std/cli/parse-args";
import { bold, green } from "@std/fmt/colors";

const args = parseArgs(Deno.args, {
  boolean: ["help", "version"],
  alias: { h: "help", v: "version" },
});

if (args.help) {
  console.log(`
${bold("my-cli")} - A Deno CLI tool

${bold("USAGE:")}
  my-cli [OPTIONS]

${bold("OPTIONS:")}
  -h, --help     Show this help message
  -v, --version  Show version
`);
  Deno.exit(0);
}

if (args.version) {
  console.log("my-cli v0.1.0");
  Deno.exit(0);
}

console.log(green("Hello from my-cli"));

Library

Create a reusable package for publishing to JSR.

Template files: See assets/library/ directory.

deno.json

{
  "name": "@username/my-library",
  "version": "0.1.0",
  "exports": "./mod.ts",
  "tasks": {
    "test": "deno test",
    "check": "deno check mod.ts",
    "publish": "deno publish"
  }
}

mod.ts

/**
 * my-library - A Deno library
 *
 * @module
 */

/**
 * Example function - replace with your library's functionality
 *
 * @param name The name to greet
 * @returns A greeting message
 *
 * @example
 * ```ts
 * import { greet } from "@username/my-library";
 * console.log(greet("World")); // "Hello, World"
 * ```
 */
export function greet(name: string): string {
  return `Hello, ${name}`;
}

mod_test.ts

import { assertEquals } from "jsr:@std/assert";
import { greet } from "./mod.ts";

Deno.test("greet returns correct message", () => {
  assertEquals(greet("World"), "Hello, World");
});

Remember: Replace @username with your JSR username before publishing.

API Server

Create a backend API without a frontend.

Template files: See assets/api-server/ directory.

deno.json

{
  "tasks": {
    "dev": "deno run --watch --allow-net main.ts",
    "start": "deno run --allow-net main.ts"
  },
  "imports": {
    "@std/http": "jsr:@std/http@^1"
  }
}

main.ts

import { serve } from "@std/http";

const handler = (request: Request): Response => {
  const url = new URL(request.url);

  if (url.pathname === "/") {
    return new Response("Welcome to the API", {
      headers: { "Content-Type": "text/plain" },
    });
  }

  if (url.pathname === "/api/hello") {
    return Response.json({ message: "Hello from Deno" });
  }

  return new Response("Not Found", { status: 404 });
};

console.log("Server running at http://localhost:8000");
serve(handler, { port: 8000 });

Post-Setup Steps

After creating project files:

cd my-project
deno install          # Install dependencies
deno fmt              # Format the code
deno lint             # Check for issues

Development Commands by Project Type

Project Type Start Development Build/Compile
Fresh deno task dev (port 5173) deno task build
CLI deno task dev deno task compile
Library deno test N/A
API deno task dev N/A

Deployment

When ready to deploy:

  • Fresh: deno task build && deno deploy --prod
  • CLI: deno task compile (creates standalone binary)
  • Library: deno publish (publishes to JSR)
  • API: deno deploy --prod

Best Practices

  • Always use jsr: imports for Deno packages (the old URL-based imports are deprecated)
  • Run deno fmt and deno lint regularly
  • Projects are configured for Deno Deploy compatibility
Weekly Installs
15
Repository
denoland/skills
GitHub Stars
58
First Seen
Feb 7, 2026
Installed on
opencode15
gemini-cli14
github-copilot14
codex14
cursor14
amp13