Skip to main content
Watch: I Asked Claude to Build Me a Business

CODE SNIPPETS

Copy-paste recipes for AI development. All TypeScript. All tested patterns.

52 snippets across 9 categories

52 snippets

Vercel AI SDKtypescript

Stream Text with Vercel AI SDK

Basic streaming text generation using the AI SDK. Returns a ReadableStream you can pipe to the client.

import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

const result = streamText({
  model: openai("gpt-4o"),
  system: "You are a helpful assistant.",
  prompt: "Explain React Server Components in 3 sentences.",
});

// Pipe to a Response (Route Handler / Server Action)
return result.toDataStreamResponse();
Vercel AI SDKtypescript

Structured Output with Zod Schema

Generate type-safe structured data from an LLM using a Zod schema. No parsing or validation needed.

import { generateObject } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

const { object } = await generateObject({
  model: openai("gpt-4o"),
  schema: z.object({
    name: z.string(),
    ingredients: z.array(z.string()),
    steps: z.array(z.string()),
    prepTime: z.number().describe("Prep time in minutes"),
  }),
  prompt: "Generate a recipe for chocolate chip cookies.",
});

console.log(object.name);
// "Classic Chocolate Chip Cookies"
Vercel AI SDKtypescript

Tool Calling with AI SDK

Define tools the model can call. The SDK handles the tool call loop automatically.

import { generateText, tool } from "ai";
import { openai } from "@ai-sdk/openai";
import { z } from "zod";

const result = await generateText({
  model: openai("gpt-4o"),
  tools: {
    weather: tool({
      description: "Get the current weather for a location",
      parameters: z.object({
        city: z.string().describe("The city name"),
      }),
      execute: async ({ city }) => {
        // Call your weather API here
        return { city, temp: 72, condition: "sunny" };
      },
    }),
  },
  maxSteps: 5,
  prompt: "What's the weather in San Francisco?",
});

console.log(result.text);
Vercel AI SDKtypescript

React Chat Hook with useChat

Full chat UI in a few lines. Handles streaming, message history, loading state, and error handling.

"use client";

import { useChat } from "@ai-sdk/react";

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit, isLoading } =
    useChat({ api: "/api/chat" });

  return (
    <div>
      {messages.map((m) => (
        <div key={m.id}>
          <strong>{m.role}:</strong> {m.content}
        </div>
      ))}

      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={handleInputChange}
          placeholder="Say something..."
          disabled={isLoading}
        />
        <button type="submit" disabled={isLoading}>
          Send
        </button>
      </form>
    </div>
  );
}
Claude APItypescript

Claude Messages API

Send a message to Claude using the Anthropic SDK. Supports system prompts, multi-turn conversations, and streaming.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const message = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  system: "You are a senior TypeScript developer.",
  messages: [
    { role: "user", content: "Write a debounce function with generics." },
  ],
});

console.log(message.content[0].type === "text" && message.content[0].text);
Claude APItypescript

Claude Tool Use

Define tools for Claude to call. Handle the tool_use response and feed results back in a conversation loop.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const response = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  tools: [
    {
      name: "get_stock_price",
      description: "Get the current stock price for a ticker symbol",
      input_schema: {
        type: "object" as const,
        properties: {
          ticker: { type: "string", description: "Stock ticker symbol" },
        },
        required: ["ticker"],
      },
    },
  ],
  messages: [{ role: "user", content: "What's the price of AAPL?" }],
});

// Check if Claude wants to use a tool
for (const block of response.content) {
  if (block.type === "tool_use") {
    console.log(`Tool: ${block.name}, Input: ${JSON.stringify(block.input)}`);
  }
}
Claude APItypescript

Claude Vision - Analyze Images

Send images to Claude for analysis. Supports base64-encoded images and URLs.

import Anthropic from "@anthropic-ai/sdk";
import { readFileSync } from "fs";

const client = new Anthropic();

const imageData = readFileSync("screenshot.png").toString("base64");

const response = await client.messages.create({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [
    {
      role: "user",
      content: [
        {
          type: "image",
          source: {
            type: "base64",
            media_type: "image/png",
            data: imageData,
          },
        },
        {
          type: "text",
          text: "Describe this UI. List any accessibility issues you see.",
        },
      ],
    },
  ],
});

console.log(response.content[0].type === "text" && response.content[0].text);
Claude APItypescript

Claude Streaming Responses

Stream responses token-by-token from Claude. Uses server-sent events under the hood.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.messages.stream({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Write a haiku about TypeScript." }],
});

for await (const event of stream) {
  if (
    event.type === "content_block_delta" &&
    event.delta.type === "text_delta"
  ) {
    process.stdout.write(event.delta.text);
  }
}

const finalMessage = await stream.finalMessage();
console.log("\nTokens used:", finalMessage.usage.input_tokens);
MCP Serverstypescript

MCP Server - Define a Tool

Create an MCP server with a custom tool. Uses the official TypeScript SDK with stdio transport.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "my-tools",
  version: "1.0.0",
});

server.tool(
  "search_docs",
  "Search documentation by keyword",
  { query: z.string(), limit: z.number().optional().default(10) },
  async ({ query, limit }) => {
    const results = await searchIndex(query, limit);
    return {
      content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
MCP Serverstypescript

MCP Server - Expose a Resource

Expose data as an MCP resource that AI clients can read. Resources are like GET endpoints for LLMs.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

const server = new McpServer({
  name: "project-context",
  version: "1.0.0",
});

// Static resource
server.resource("readme", "file:///readme", async (uri) => ({
  contents: [
    {
      uri: uri.href,
      mimeType: "text/markdown",
      text: "# My Project\nThis is the project README.",
    },
  ],
}));

// Dynamic resource with template
server.resource(
  "user-profile",
  "users://{userId}/profile",
  async (uri, { userId }) => {
    const user = await db.getUser(userId);
    return {
      contents: [
        {
          uri: uri.href,
          mimeType: "application/json",
          text: JSON.stringify(user),
        },
      ],
    };
  }
);

const transport = new StdioServerTransport();
await server.connect(transport);
MCP Serverstypescript

MCP Server - Define a Prompt

Create reusable prompt templates that AI clients can discover and use. Prompts are like stored procedures for LLMs.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "prompts",
  version: "1.0.0",
});

server.prompt(
  "code-review",
  "Review code for bugs, security issues, and style",
  { language: z.string(), code: z.string() },
  ({ language, code }) => ({
    messages: [
      {
        role: "user",
        content: {
          type: "text",
          text: [
            `Review this ${language} code.`,
            "Check for: bugs, security issues, performance, readability.",
            "Format: list each issue with severity (high/medium/low).",
            "",
            `\`\`\`${language}`,
            code,
            "\`\`\`",
          ].join("\n"),
        },
      },
    ],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);
Next.js + AItypescript

AI Route Handler (App Router)

A POST route handler that streams AI responses. Drop this in app/api/chat/route.ts.

// app/api/chat/route.ts
import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";

export async function POST(req: Request) {
  const { messages } = await req.json();

  const result = streamText({
    model: openai("gpt-4o"),
    system: "You are a helpful coding assistant.",
    messages,
  });

  return result.toDataStreamResponse();
}
Next.js + AItypescript

AI Server Action with Streaming

Call an LLM from a Server Action and stream the result to the client using createStreamableValue.

// app/actions.ts
"use server";

import { streamText } from "ai";
import { openai } from "@ai-sdk/openai";
import { createStreamableValue } from "ai/rsc";

export async function generate(prompt: string) {
  const stream = createStreamableValue("");

  (async () => {
    const result = streamText({
      model: openai("gpt-4o"),
      prompt,
    });

    for await (const delta of result.textStream) {
      stream.update(delta);
    }

    stream.done();
  })();

  return { output: stream.value };
}
Next.js + AItypescript

Streaming UI Components

Render AI-generated content as it streams in. Uses useChat for real-time updates with a loading indicator.

"use client";

import { useChat } from "@ai-sdk/react";

export default function StreamingChat() {
  const { messages, input, handleInputChange, handleSubmit, status } =
    useChat();

  return (
    <div className="max-w-2xl mx-auto p-4">
      <div className="space-y-4 mb-4">
        {messages.map((m) => (
          <div
            key={m.id}
            className={m.role === "user" ? "text-right" : "text-left"}
          >
            <div
              className={`inline-block p-3 rounded-lg ${
                m.role === "user"
                  ? "bg-black text-white"
                  : "bg-gray-100 text-black"
              }`}
            >
              {m.content}
            </div>
          </div>
        ))}
        {status === "streaming" && (
          <div className="text-gray-400 animate-pulse">Thinking...</div>
        )}
      </div>

      <form onSubmit={handleSubmit} className="flex gap-2">
        <input
          value={input}
          onChange={handleInputChange}
          className="flex-1 border rounded-full px-4 py-2"
          placeholder="Ask something..."
        />
        <button
          type="submit"
          className="bg-black text-white px-6 py-2 rounded-full"
        >
          Send
        </button>
      </form>
    </div>
  );
}
Next.js + AItypescript

Rate Limiting AI Endpoints

Simple in-memory rate limiter for AI API routes. Prevents abuse and controls costs.

// lib/rate-limit.ts
const rateLimit = new Map<string, { count: number; resetTime: number }>();

export function checkRateLimit(
  ip: string,
  limit = 10,
  windowMs = 60_000
): { allowed: boolean; remaining: number } {
  const now = Date.now();
  const entry = rateLimit.get(ip);

  if (!entry || now > entry.resetTime) {
    rateLimit.set(ip, { count: 1, resetTime: now + windowMs });
    return { allowed: true, remaining: limit - 1 };
  }

  if (entry.count >= limit) {
    return { allowed: false, remaining: 0 };
  }

  entry.count++;
  return { allowed: true, remaining: limit - entry.count };
}

// Usage in route handler:
// const ip = req.headers.get("x-forwarded-for") ?? "unknown";
// const { allowed } = checkRateLimit(ip);
// if (!allowed) return new Response("Too many requests", { status: 429 });
Convex + AItypescript

Convex Action with AI

Call an LLM from a Convex action and store the result in the database. Actions can make external API calls.

// convex/ai.ts
import { action } from "./_generated/server";
import { v } from "convex/values";
import Anthropic from "@anthropic-ai/sdk";

export const summarize = action({
  args: { text: v.string(), documentId: v.id("documents") },
  handler: async (ctx, { text, documentId }) => {
    const client = new Anthropic();

    const message = await client.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 512,
      messages: [
        {
          role: "user",
          content: `Summarize this in 2-3 sentences:\n\n${text}`,
        },
      ],
    });

    const summary =
      message.content[0].type === "text" ? message.content[0].text : "";

    // Store the summary back in the database
    await ctx.runMutation(api.documents.updateSummary, {
      id: documentId,
      summary,
    });

    return summary;
  },
});
Convex + AItypescript

Convex Cron Job with AI

Schedule a recurring AI task using Convex cron jobs. Runs a daily content digest.

// convex/crons.ts
import { cronJobs } from "convex/server";
import { internal } from "./_generated/api";

const crons = cronJobs();

// Run every day at 9am UTC
crons.daily(
  "daily-digest",
  { hourUTC: 9, minuteUTC: 0 },
  internal.digest.generateDailyDigest
);

export default crons;

// convex/digest.ts
import { internalAction } from "./_generated/server";
import { internal } from "./_generated/api";

export const generateDailyDigest = internalAction({
  handler: async (ctx) => {
    // Fetch recent items from the database
    const items = await ctx.runQuery(internal.items.getRecent, {
      since: Date.now() - 86_400_000,
    });

    // Generate digest with AI
    const digest = await generateWithAI(
      `Create a brief digest of these ${items.length} items: ${JSON.stringify(items)}`
    );

    // Store the digest
    await ctx.runMutation(internal.digests.store, {
      content: digest,
      date: new Date().toISOString().slice(0, 10),
    });
  },
});
Convex + AItypescript

Convex Vector Search for RAG

Semantic search with Convex vector indexes. Embed documents and query by similarity for RAG pipelines.

// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  documents: defineTable({
    title: v.string(),
    content: v.string(),
    embedding: v.array(v.float64()),
  }).vectorIndex("by_embedding", {
    vectorField: "embedding",
    dimensions: 1536,
  }),
});

// convex/search.ts
import { action } from "./_generated/server";
import { v } from "convex/values";
import { internal } from "./_generated/api";

export const searchSimilar = action({
  args: { query: v.string(), limit: v.optional(v.number()) },
  handler: async (ctx, { query, limit = 5 }) => {
    // Generate embedding for the query
    const embedding = await getEmbedding(query);

    // Search by vector similarity
    const results = await ctx.vectorSearch("documents", "by_embedding", {
      vector: embedding,
      limit,
    });

    return results;
  },
});
Utilitiestypescript

Estimate Token Count

Quick token estimation without external dependencies. Good enough for context window management and cost estimates.

function estimateTokens(text: string): number {
  // GPT/Claude models average ~4 characters per token for English text.
  // This is a rough estimate - use tiktoken for exact counts.
  return Math.ceil(text.length / 4);
}

function estimateCost(
  inputTokens: number,
  outputTokens: number,
  model: "gpt-4o" | "claude-sonnet" | "claude-haiku"
): number {
  const pricing = {
    "gpt-4o": { input: 2.5 / 1_000_000, output: 10 / 1_000_000 },
    "claude-sonnet": { input: 3 / 1_000_000, output: 15 / 1_000_000 },
    "claude-haiku": { input: 0.25 / 1_000_000, output: 1.25 / 1_000_000 },
  };
  const p = pricing[model];
  return inputTokens * p.input + outputTokens * p.output;
}

// Usage
const text = "Hello, how are you doing today?";
const tokens = estimateTokens(text);
const cost = estimateCost(tokens, 200, "claude-sonnet");
console.log(`~${tokens} input tokens, estimated cost: $${cost.toFixed(4)}`);
Utilitiestypescript

Type-Safe Prompt Templates

Build reusable prompt templates with typed variables. Catches missing variables at compile time.

type PromptVars<T extends string> = Record<T, string>;

function createPrompt<T extends string>(
  template: string,
  vars: PromptVars<T>
): string {
  return Object.entries<string>(vars).reduce(
    (prompt, [key, value]) =>
      prompt.replaceAll(`{{${key}}}`, value),
    template
  );
}

// Define templates
const templates = {
  codeReview: `You are a senior {{language}} developer.
Review this code for bugs, security issues, and performance.

\`\`\`{{language}}
{{code}}
\`\`\`

Focus on: {{focus}}`,

  summarize: `Summarize the following {{contentType}} in {{length}} sentences.
Audience: {{audience}}.

{{content}}`,
} as const;

// Usage
const prompt = createPrompt(templates.codeReview, {
  language: "TypeScript",
  code: "const data = JSON.parse(userInput);",
  focus: "security vulnerabilities",
});
Utilitiestypescript

Retry with Exponential Backoff

Wrap any async function with automatic retries and exponential backoff. Essential for flaky AI API calls.

async function withRetry<T>(
  fn: () => Promise<T>,
  opts: { maxRetries?: number; baseDelay?: number; maxDelay?: number } = {}
): Promise<T> {
  const { maxRetries = 3, baseDelay = 1000, maxDelay = 30_000 } = opts;

  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await fn();
    } catch (error: unknown) {
      if (attempt === maxRetries) throw error;

      // Don't retry client errors (4xx except 429)
      if (error instanceof Error && "status" in error) {
        const status = (error as { status: number }).status;
        if (status >= 400 && status < 500 && status !== 429) throw error;
      }

      const delay = Math.min(baseDelay * 2 ** attempt, maxDelay);
      const jitter = delay * (0.5 + Math.random() * 0.5);
      await new Promise((r) => setTimeout(r, jitter));
    }
  }

  throw new Error("Unreachable");
}

// Usage
const response = await withRetry(
  () => client.messages.create({ model: "claude-sonnet-4-20250514", max_tokens: 1024, messages }),
  { maxRetries: 3, baseDelay: 1000 }
);
Utilitiestypescript

AI API Error Handling

Comprehensive error handling for AI API calls. Covers rate limits, context length, and network errors.

interface AIError {
  type: "rate_limit" | "context_length" | "auth" | "server" | "network" | "unknown";
  message: string;
  retryable: boolean;
  retryAfter?: number;
}

function classifyError(error: unknown): AIError {
  if (error instanceof Error && "status" in error) {
    const status = (error as { status: number }).status;
    const msg = error.message;

    if (status === 429) {
      return {
        type: "rate_limit",
        message: "Rate limit exceeded. Slow down requests.",
        retryable: true,
        retryAfter: 60,
      };
    }
    if (status === 400 && msg.includes("context")) {
      return {
        type: "context_length",
        message: "Input too long. Reduce prompt or conversation history.",
        retryable: false,
      };
    }
    if (status === 401 || status === 403) {
      return {
        type: "auth",
        message: "Invalid or expired API key.",
        retryable: false,
      };
    }
    if (status >= 500) {
      return {
        type: "server",
        message: "AI provider is having issues. Try again shortly.",
        retryable: true,
        retryAfter: 5,
      };
    }
  }

  if (error instanceof TypeError && (error.message.includes("fetch") || error.message.includes("network"))) {
    return { type: "network", message: "Network error.", retryable: true };
  }

  return { type: "unknown", message: String(error), retryable: false };
}
AI/LLM Integrationtypescript

Streaming Chat Completion (OpenAI SDK)

Stream chat completions from OpenAI token-by-token. Works with any OpenAI-compatible API endpoint.

import OpenAI from "openai";

const client = new OpenAI();

const stream = await client.chat.completions.create({
  model: "gpt-4o",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Explain monads in plain English." },
  ],
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) {
    process.stdout.write(content);
  }
}
AI/LLM Integrationtypescript

Streaming Chat Completion (Anthropic SDK)

Stream responses from Claude using the Anthropic SDK. Handles content block deltas and final message metadata.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.messages.stream({
  model: "claude-sonnet-4-20250514",
  max_tokens: 1024,
  system: "You are a senior TypeScript developer.",
  messages: [
    { role: "user", content: "Explain the builder pattern with an example." },
  ],
});

stream.on("text", (text) => {
  process.stdout.write(text);
});

const finalMessage = await stream.finalMessage();
console.log("\nInput tokens:", finalMessage.usage.input_tokens);
console.log("Output tokens:", finalMessage.usage.output_tokens);
AI/LLM Integrationtypescript

Tool/Function Calling Setup

Define tools with JSON Schema and handle the tool call loop. Works with OpenAI, Anthropic, or any function-calling provider.

import OpenAI from "openai";

const client = new OpenAI();

const tools: OpenAI.ChatCompletionTool[] = [
  {
    type: "function",
    function: {
      name: "get_weather",
      description: "Get current weather for a city",
      parameters: {
        type: "object",
        properties: {
          city: { type: "string", description: "City name" },
          units: { type: "string", enum: ["celsius", "fahrenheit"] },
        },
        required: ["city"],
      },
    },
  },
];

const handlers: Record<string, (args: Record<string, unknown>) => Promise<string>> = {
  get_weather: async ({ city, units }) => {
    return JSON.stringify({ city, temp: 22, units: units ?? "celsius" });
  },
};

const messages: OpenAI.ChatCompletionMessageParam[] = [
  { role: "user", content: "What's the weather in Tokyo?" },
];

let response = await client.chat.completions.create({
  model: "gpt-4o", messages, tools,
});

// Tool call loop
while (response.choices[0].finish_reason === "tool_calls") {
  const toolCalls = response.choices[0].message.tool_calls!;
  messages.push(response.choices[0].message);

  for (const call of toolCalls) {
    const result = await handlers[call.function.name](
      JSON.parse(call.function.arguments)
    );
    messages.push({ role: "tool", tool_call_id: call.id, content: result });
  }

  response = await client.chat.completions.create({
    model: "gpt-4o", messages, tools,
  });
}

console.log(response.choices[0].message.content);
AI/LLM Integrationtypescript

RAG with Embeddings + Cosine Similarity

Build a simple RAG pipeline: embed documents, store vectors, and retrieve the most relevant chunks using cosine similarity.

import OpenAI from "openai";

const client = new OpenAI();

async function embed(texts: string[]): Promise<number[][]> {
  const res = await client.embeddings.create({
    model: "text-embedding-3-small",
    input: texts,
  });
  return res.data.map((d) => d.embedding);
}

function cosineSimilarity(a: number[], b: number[]): number {
  let dot = 0, magA = 0, magB = 0;
  for (let i = 0; i < a.length; i++) {
    dot += a[i] * b[i];
    magA += a[i] * a[i];
    magB += b[i] * b[i];
  }
  return dot / (Math.sqrt(magA) * Math.sqrt(magB));
}

interface Doc { text: string; embedding: number[] }
const store: Doc[] = [];

async function addDocuments(texts: string[]) {
  const embeddings = await embed(texts);
  texts.forEach((text, i) => store.push({ text, embedding: embeddings[i] }));
}

async function search(query: string, topK = 3): Promise<string[]> {
  const [queryEmb] = await embed([query]);
  return store
    .map((doc) => ({ text: doc.text, score: cosineSimilarity(queryEmb, doc.embedding) }))
    .sort((a, b) => b.score - a.score)
    .slice(0, topK)
    .map((r) => r.text);
}

// Usage
await addDocuments([
  "TypeScript supports generics for type-safe reusable code.",
  "Next.js App Router uses React Server Components by default.",
  "Convex provides real-time reactive queries out of the box.",
]);

const relevant = await search("How do I use generics?");
console.log(relevant);
AI/LLM Integrationtypescript

MCP Server Skeleton (TypeScript)

Complete MCP server boilerplate with a tool, resource, and prompt. Ready to extend with your own logic.

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

const server = new McpServer({
  name: "my-mcp-server",
  version: "1.0.0",
});

server.tool(
  "lookup",
  "Look up information by key",
  { key: z.string().describe("The lookup key") },
  async ({ key }) => {
    const data: Record<string, string> = { version: "2.1.0", status: "healthy" };
    const value = data[key] ?? "Not found";
    return { content: [{ type: "text", text: value }] };
  }
);

server.resource("config", "config://app", async (uri) => ({
  contents: [{
    uri: uri.href,
    mimeType: "application/json",
    text: JSON.stringify({ env: "production", debug: false }),
  }],
}));

server.prompt(
  "explain",
  "Explain a concept simply",
  { topic: z.string() },
  ({ topic }) => ({
    messages: [{
      role: "user",
      content: {
        type: "text",
        text: `Explain ${topic} like I'm a junior developer. Use an analogy.`,
      },
    }],
  })
);

const transport = new StdioServerTransport();
await server.connect(transport);
console.error("MCP server running on stdio");
AI/LLM Integrationtypescript

MCP Client Connection

Connect to an MCP server from a client. Discover and call tools, read resources, and use prompts programmatically.

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";

const transport = new StdioClientTransport({
  command: "node",
  args: ["./my-mcp-server.js"],
});

const client = new Client(
  { name: "my-client", version: "1.0.0" },
  { capabilities: {} }
);

await client.connect(transport);

// List available tools
const { tools } = await client.listTools();
console.log("Available tools:", tools.map((t) => t.name));

// Call a tool
const result = await client.callTool({
  name: "lookup",
  arguments: { key: "version" },
});
console.log("Tool result:", result.content);

// Read a resource
const { contents } = await client.readResource({ uri: "config://app" });
console.log("Resource:", contents[0].text);

// Use a prompt
const { messages } = await client.getPrompt({
  name: "explain",
  arguments: { topic: "dependency injection" },
});
console.log("Prompt:", messages[0].content);

await client.close();
AI/LLM Integrationtypescript

Agent Loop with Retry Logic

A basic agent loop that calls tools, handles errors, and retries. Foundation for any agentic workflow.

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const toolHandlers: Record<string, (input: Record<string, unknown>) => Promise<string>> = {
  read_file: async ({ path }) => {
    const { readFileSync } = await import("fs");
    return readFileSync(path as string, "utf-8");
  },
  run_command: async ({ command }) => {
    const { execSync } = await import("child_process");
    return execSync(command as string, { encoding: "utf-8", timeout: 30_000 });
  },
};

async function agentLoop(task: string, maxTurns = 10) {
  const messages: Anthropic.MessageParam[] = [{ role: "user", content: task }];

  for (let turn = 0; turn < maxTurns; turn++) {
    const response = await client.messages.create({
      model: "claude-sonnet-4-20250514",
      max_tokens: 4096,
      tools: [
        { name: "read_file", description: "Read a file",
          input_schema: { type: "object" as const, properties: { path: { type: "string" } }, required: ["path"] } },
        { name: "run_command", description: "Run a shell command",
          input_schema: { type: "object" as const, properties: { command: { type: "string" } }, required: ["command"] } },
      ],
      messages,
    });

    messages.push({ role: "assistant", content: response.content });

    if (response.stop_reason === "end_turn") {
      const text = response.content.find((b) => b.type === "text");
      return text?.type === "text" ? text.text : "Done.";
    }

    const toolResults: Anthropic.ToolResultBlockParam[] = [];
    for (const block of response.content) {
      if (block.type === "tool_use") {
        try {
          const result = await toolHandlers[block.name](block.input as Record<string, unknown>);
          toolResults.push({ type: "tool_result", tool_use_id: block.id, content: result });
        } catch (err) {
          toolResults.push({ type: "tool_result", tool_use_id: block.id, content: String(err), is_error: true });
        }
      }
    }
    messages.push({ role: "user", content: toolResults });
  }
  return "Max turns reached.";
}

const result = await agentLoop("Read package.json and tell me the project name.");
console.log(result);
AI/LLM Integrationtypescript

Structured Output with Zod

Force an LLM to return data matching a Zod schema. Parse, validate, and get full type inference on the result.

import OpenAI from "openai";
import { z } from "zod";
import { zodResponseFormat } from "openai/helpers/zod";

const client = new OpenAI();

const EventSchema = z.object({
  title: z.string(),
  date: z.string().describe("ISO 8601 date string"),
  location: z.string(),
  attendees: z.array(z.object({
    name: z.string(),
    role: z.enum(["speaker", "organizer", "attendee"]),
  })),
  isVirtual: z.boolean(),
});

type Event = z.infer<typeof EventSchema>;

const completion = await client.beta.chat.completions.parse({
  model: "gpt-4o",
  messages: [
    { role: "system", content: "Extract event details from the text." },
    { role: "user", content: "React Conf 2025 is May 15 in Las Vegas. Sarah Chen is speaking. Mike Torres is organizing." },
  ],
  response_format: zodResponseFormat(EventSchema, "event"),
});

const event: Event | null = completion.choices[0].message.parsed;
console.log(event?.title);     // "React Conf 2025"
console.log(event?.attendees); // [{ name: "Sarah Chen", role: "speaker" }, ...]
AI/LLM Integrationtypescript

Multi-Model Fallback Chain

Try multiple AI providers in sequence. If the primary model fails or is rate-limited, fall through to the next one.

import Anthropic from "@anthropic-ai/sdk";
import OpenAI from "openai";

interface ModelConfig {
  name: string;
  call: (prompt: string) => Promise<string>;
}

const models: ModelConfig[] = [
  {
    name: "claude-sonnet",
    call: async (prompt) => {
      const client = new Anthropic();
      const res = await client.messages.create({
        model: "claude-sonnet-4-20250514", max_tokens: 1024,
        messages: [{ role: "user", content: prompt }],
      });
      const block = res.content[0];
      return block.type === "text" ? block.text : "";
    },
  },
  {
    name: "gpt-4o",
    call: async (prompt) => {
      const client = new OpenAI();
      const res = await client.chat.completions.create({
        model: "gpt-4o",
        messages: [{ role: "user", content: prompt }],
      });
      return res.choices[0].message.content ?? "";
    },
  },
  {
    name: "gpt-4o-mini",
    call: async (prompt) => {
      const client = new OpenAI();
      const res = await client.chat.completions.create({
        model: "gpt-4o-mini",
        messages: [{ role: "user", content: prompt }],
      });
      return res.choices[0].message.content ?? "";
    },
  },
];

async function generateWithFallback(
  prompt: string
): Promise<{ text: string; model: string }> {
  for (const model of models) {
    try {
      const text = await model.call(prompt);
      return { text, model: model.name };
    } catch (err) {
      console.error(`${model.name} failed: ${err instanceof Error ? err.message : err}`);
    }
  }
  throw new Error("All models failed");
}

const { text, model } = await generateWithFallback("Explain closures in JS.");
console.log(`[${model}] ${text}`);
AI/LLM Integrationtypescript

Token Counting Utility

Count tokens accurately using tiktoken for OpenAI models or a character-based estimate for others.

import { encoding_for_model, type TiktokenModel } from "tiktoken";

function countTokensExact(text: string, model: TiktokenModel = "gpt-4o"): number {
  const enc = encoding_for_model(model);
  const tokens = enc.encode(text);
  enc.free();
  return tokens.length;
}

function countTokensEstimate(text: string): number {
  const codeRatio = (text.match(/[{}();=<>]/g)?.length ?? 0) / text.length;
  const charsPerToken = codeRatio > 0.05 ? 3 : 4;
  return Math.ceil(text.length / charsPerToken);
}

function countMessageTokens(
  messages: { role: string; content: string }[],
  model: TiktokenModel = "gpt-4o"
): number {
  const enc = encoding_for_model(model);
  let total = 0;
  for (const msg of messages) {
    total += 4; // message overhead
    total += enc.encode(msg.role).length;
    total += enc.encode(msg.content).length;
  }
  total += 2; // assistant reply priming
  enc.free();
  return total;
}

// Usage
const code = "function add(a: number, b: number) { return a + b; }";
console.log("Exact:", countTokensExact(code));
console.log("Estimate:", countTokensEstimate(code));

const msgs = [
  { role: "system", content: "You are a helpful assistant." },
  { role: "user", content: "What is TypeScript?" },
];
console.log("Messages:", countMessageTokens(msgs));
Next.js Patternstypescript

Server Action with Validation

A type-safe Server Action with Zod validation, proper error handling, and a client form using useActionState.

// app/actions/contact.ts
"use server";

import { z } from "zod";

const ContactSchema = z.object({
  name: z.string().min(2, "Name must be at least 2 characters"),
  email: z.string().email("Invalid email address"),
  message: z.string().min(10, "Message must be at least 10 characters"),
});

type ActionState = {
  success: boolean;
  message: string;
  errors?: Record<string, string[]>;
};

export async function submitContact(
  _prev: ActionState,
  formData: FormData
): Promise<ActionState> {
  const raw = Object.fromEntries(formData);
  const parsed = ContactSchema.safeParse(raw);

  if (!parsed.success) {
    return {
      success: false,
      message: "Validation failed",
      errors: parsed.error.flatten().fieldErrors,
    };
  }

  try {
    await saveToDatabase(parsed.data);
    return { success: true, message: "Message sent!" };
  } catch {
    return { success: false, message: "Something went wrong." };
  }
}

// Client usage:
// const [state, action, pending] = useActionState(submitContact, {
//   success: false, message: "",
// });
Next.js Patternstypescript

Middleware Auth Check

Protect routes with Next.js middleware. Redirects unauthenticated users and handles public paths.

// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

const PUBLIC = ["/", "/login", "/signup", "/api/auth", "/api/webhook"];

function isPublic(path: string) {
  return PUBLIC.some((p) => path === p || path.startsWith(p + "/"));
}

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  if (isPublic(pathname)) return NextResponse.next();

  const token = request.cookies.get("session-token")?.value;
  if (!token) {
    const url = new URL("/login", request.url);
    url.searchParams.set("redirect", pathname);
    return NextResponse.redirect(url);
  }

  try {
    const payload = JSON.parse(atob(token.split(".")[1]));
    if (payload.exp * 1000 < Date.now()) {
      return NextResponse.redirect(new URL("/login", request.url));
    }
  } catch {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)"],
};
Next.js Patternstypescript

Dynamic OG Image Generation

Generate dynamic Open Graph images at the edge using next/og. Perfect for blog posts and social cards.

// app/api/og/route.tsx
import { ImageResponse } from "next/og";
import type { NextRequest } from "next/server";

export const runtime = "edge";

export async function GET(request: NextRequest) {
  const { searchParams } = request.nextUrl;
  const title = searchParams.get("title") ?? "Default Title";
  const subtitle = searchParams.get("subtitle") ?? "";

  return new ImageResponse(
    (
      <div style={{
        height: "100%", width: "100%", display: "flex",
        flexDirection: "column", justifyContent: "center",
        padding: "60px 80px", backgroundColor: "#F4F4F0",
      }}>
        <div style={{
          display: "flex", flexDirection: "column",
          border: "3px solid #000", borderRadius: "24px",
          padding: "48px", backgroundColor: "#fff",
        }}>
          <div style={{ fontSize: 52, fontWeight: 900 }}>{title}</div>
          {subtitle && (
            <div style={{ fontSize: 28, color: "#666", marginTop: 16 }}>
              {subtitle}
            </div>
          )}
          <div style={{ fontSize: 24, fontWeight: 700, marginTop: 32 }}>
            developersdigest.tech
          </div>
        </div>
      </div>
    ),
    { width: 1200, height: 630 }
  );
}
Next.js Patternstypescript

ISR with On-Demand Revalidation

Incremental Static Regeneration with time-based and on-demand revalidation via API endpoint.

// app/blog/[slug]/page.tsx
import { notFound } from "next/navigation";

export const revalidate = 60; // seconds

export async function generateStaticParams() {
  const posts = await getTopPosts(20);
  return posts.map((post) => ({ slug: post.slug }));
}

export default async function BlogPost({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  const post = await getPostBySlug(slug);
  if (!post) notFound();

  // Sanitize CMS HTML at the trust boundary before the sink.
  const safeHtml = sanitizeHtml(post.html);

  return (
    <article>
      <h1>{post.title}</h1>
      <div dangerouslySetInnerHTML={{ __html: safeHtml }} />
    </article>
  );
}

// app/api/revalidate/route.ts
import { revalidatePath, revalidateTag } from "next/cache";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export async function POST(request: NextRequest) {
  const secret = request.headers.get("x-revalidate-secret");
  if (secret !== process.env.REVALIDATE_SECRET) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const { path, tag } = await request.json();
  if (tag) revalidateTag(tag);
  else if (path) revalidatePath(path);
  else return NextResponse.json({ error: "Missing path or tag" }, { status: 400 });

  return NextResponse.json({ revalidated: true, now: Date.now() });
}
Next.js Patternstypescript

Parallel Data Fetching

Fetch multiple data sources in parallel with Promise.all. Avoids waterfall requests in Server Components.

// app/dashboard/page.tsx
async function getUser(id: string) {
  const res = await fetch(`https://api.example.com/users/${id}`, {
    next: { revalidate: 300 },
  });
  return res.json() as Promise<{ name: string; email: string }>;
}

async function getStats(id: string) {
  const res = await fetch(`https://api.example.com/users/${id}/stats`, {
    next: { revalidate: 60 },
  });
  return res.json() as Promise<{ posts: number; views: number }>;
}

async function getNotifications(id: string) {
  const res = await fetch(`https://api.example.com/users/${id}/notifications`, {
    cache: "no-store",
  });
  return res.json() as Promise<{ id: string; message: string }[]>;
}

export default async function Dashboard() {
  const userId = "user_123";

  // All three fire simultaneously
  const [user, stats, notifications] = await Promise.all([
    getUser(userId),
    getStats(userId),
    getNotifications(userId),
  ]);

  return (
    <div>
      <h1>Welcome, {user.name}</h1>
      <p>{stats.posts} posts, {stats.views} views</p>
      <h2>Notifications ({notifications.length})</h2>
      <ul>
        {notifications.map((n) => (
          <li key={n.id}>{n.message}</li>
        ))}
      </ul>
    </div>
  );
}
Next.js Patternstypescript

Error Boundary with Recovery

Next.js error boundary with retry functionality. Catches errors at the route segment level.

// app/dashboard/error.tsx
"use client";

import { useEffect } from "react";

export default function DashboardError({
  error,
  reset,
}: {
  error: Error & { digest?: string };
  reset: () => void;
}) {
  useEffect(() => {
    console.error("Dashboard error:", error);
  }, [error]);

  return (
    <div className="flex flex-col items-center justify-center min-h-[400px] p-8">
      <h2 className="text-2xl font-bold mb-4">Something went wrong</h2>
      <p className="text-gray-600 mb-6 text-center max-w-md">
        {error.message || "An unexpected error occurred."}
      </p>
      {error.digest && (
        <p className="text-xs text-gray-400 mb-4">Error ID: {error.digest}</p>
      )}
      <div className="flex gap-3">
        <button
          onClick={reset}
          className="px-6 py-2 bg-black text-white rounded-full font-medium"
        >
          Try again
        </button>
        <a
          href="/"
          className="px-6 py-2 border-2 border-black rounded-full font-medium"
        >
          Go home
        </a>
      </div>
    </div>
  );
}
Next.js Patternstypescript

Streaming SSR with Suspense

Stream page content progressively using Suspense. The shell renders instantly while slow data loads in.

import { Suspense } from "react";

async function getUser() {
  const res = await fetch("https://api.example.com/user", { cache: "no-store" });
  return res.json() as Promise<{ name: string }>;
}

async function AnalyticsPanel() {
  const res = await fetch("https://api.example.com/analytics", { cache: "no-store" });
  const data = (await res.json()) as { views: number; revenue: number };
  return (
    <div className="border rounded-xl p-6">
      <h2 className="font-bold mb-2">Analytics</h2>
      <p>{data.views.toLocaleString()} views</p>
    </div>
  );
}

async function RecommendationsPanel() {
  const res = await fetch("https://api.example.com/recs", { cache: "no-store" });
  const items = (await res.json()) as { title: string; url: string }[];
  return (
    <div className="border rounded-xl p-6">
      <h2 className="font-bold mb-2">Recommended</h2>
      <ul>{items.map((i) => <li key={i.url}><a href={i.url}>{i.title}</a></li>)}</ul>
    </div>
  );
}

function Skeleton() {
  return (
    <div className="border rounded-xl p-6 animate-pulse">
      <div className="h-6 bg-gray-200 rounded w-1/3 mb-4" />
      <div className="h-4 bg-gray-200 rounded w-2/3" />
    </div>
  );
}

export default async function Dashboard() {
  const user = await getUser();
  return (
    <div className="p-8">
      <h1 className="text-3xl font-bold mb-8">Welcome, {user.name}</h1>
      <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
        <Suspense fallback={<Skeleton />}><AnalyticsPanel /></Suspense>
        <Suspense fallback={<Skeleton />}><RecommendationsPanel /></Suspense>
      </div>
    </div>
  );
}
Next.js Patternstypescript

Route Handler with Rate Limiting

API route with sliding-window rate limiting. Returns rate limit headers to clients.

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

const windows = new Map<string, number[]>();

function rateLimit(key: string, limit: number, windowMs: number) {
  const now = Date.now();
  const timestamps = (windows.get(key) ?? []).filter((t) => t > now - windowMs);

  if (timestamps.length >= limit) {
    return { allowed: false, remaining: 0, resetAt: timestamps[0] + windowMs };
  }

  timestamps.push(now);
  windows.set(key, timestamps);
  return { allowed: true, remaining: limit - timestamps.length, resetAt: now + windowMs };
}

export async function POST(request: NextRequest) {
  const ip = request.headers.get("x-forwarded-for") ?? "anon";
  const { allowed, remaining, resetAt } = rateLimit(ip, 20, 60_000);

  const headers = {
    "X-RateLimit-Limit": "20",
    "X-RateLimit-Remaining": String(remaining),
    "X-RateLimit-Reset": String(Math.ceil(resetAt / 1000)),
  };

  if (!allowed) {
    return NextResponse.json(
      { error: "Rate limit exceeded" },
      { status: 429, headers: {
        ...headers,
        "Retry-After": String(Math.ceil((resetAt - Date.now()) / 1000)),
      }}
    );
  }

  const body = await request.json();
  return NextResponse.json({ success: true, data: body }, { headers });
}
Next.js Patternstypescript

Convex Real-Time Subscription

Subscribe to live data from Convex. Data updates automatically when the database changes.

// convex/schema.ts
import { defineSchema, defineTable } from "convex/server";
import { v } from "convex/values";

export default defineSchema({
  messages: defineTable({
    author: v.string(),
    body: v.string(),
    createdAt: v.number(),
  }).index("by_time", ["createdAt"]),
});

// convex/messages.ts
import { query, mutation } from "./_generated/server";
import { v } from "convex/values";

export const list = query({
  args: { limit: v.optional(v.number()) },
  handler: async (ctx, { limit = 50 }) => {
    return ctx.db.query("messages")
      .withIndex("by_time")
      .order("desc")
      .take(limit);
  },
});

export const send = mutation({
  args: { author: v.string(), body: v.string() },
  handler: async (ctx, { author, body }) => {
    await ctx.db.insert("messages", { author, body, createdAt: Date.now() });
  },
});

// Client component:
// "use client";
// import { useQuery, useMutation } from "convex/react";
// import { api } from "@/convex/_generated/api";
//
// const messages = useQuery(api.messages.list, { limit: 50 });
// const send = useMutation(api.messages.send);
// await send({ author: "User", body: "Hello!" });
Next.js Patternstypescript

Clerk Auth Wrapper

Protect pages and API routes with Clerk. Includes middleware, server-side auth, and API route protection.

// middleware.ts
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";

const isProtected = createRouteMatcher(["/dashboard(.*)", "/settings(.*)", "/api/user(.*)"]);

export default clerkMiddleware(async (auth, request) => {
  if (isProtected(request)) await auth.protect();
});

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\..*).*)"],
};

// app/dashboard/page.tsx
import { auth, currentUser } from "@clerk/nextjs/server";
import { redirect } from "next/navigation";

export default async function DashboardPage() {
  const { userId } = await auth();
  if (!userId) redirect("/sign-in");

  const user = await currentUser();
  return (
    <div>
      <h1>Welcome, {user?.firstName ?? "there"}</h1>
      <p>Email: {user?.emailAddresses[0]?.emailAddress}</p>
    </div>
  );
}

// app/api/user/route.ts
import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";

export async function GET() {
  const { userId } = await auth();
  if (!userId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  const data = await getUserFromDb(userId);
  return NextResponse.json(data);
}
CLI/DevOpstypescript

Commander CLI Skeleton

Boilerplate for a Node.js CLI tool using Commander. Includes subcommands, options, and arguments.

#!/usr/bin/env node
import { Command } from "commander";
import { readFileSync } from "fs";

const pkg = JSON.parse(readFileSync("./package.json", "utf-8"));

const program = new Command()
  .name("mycli")
  .description("A useful CLI tool")
  .version(pkg.version);

program
  .command("init")
  .description("Initialize a new project")
  .option("-t, --template <name>", "template to use", "default")
  .option("--no-git", "skip git initialization")
  .action(async (opts) => {
    console.log(`Template: ${opts.template}, Git: ${opts.git}`);
  });

program
  .command("build")
  .description("Build the project")
  .option("-w, --watch", "watch for changes")
  .option("-o, --output <dir>", "output directory", "dist")
  .action(async (opts) => {
    console.log(`Building to ${opts.output}...`);
    if (opts.watch) console.log("Watching...");
  });

program
  .command("deploy")
  .description("Deploy to production")
  .argument("<environment>", "target environment")
  .option("--dry-run", "simulate deployment")
  .action(async (env, opts) => {
    console.log(`Deploying to ${env}${opts.dryRun ? " (dry run)" : ""}`);
  });

program.parse();
CLI/DevOpstypescript

Interactive Prompts (Inquirer)

Build interactive CLI prompts with @inquirer/prompts. Text input, selections, confirmations, and multi-select.

import { input, select, confirm, checkbox } from "@inquirer/prompts";

async function setup() {
  const name = await input({
    message: "Project name:",
    default: "my-app",
    validate: (v) => /^[a-z0-9-]+$/.test(v) || "Lowercase, numbers, dashes only",
  });

  const framework = await select({
    message: "Framework:",
    choices: [
      { name: "Next.js", value: "nextjs", description: "Full-stack React" },
      { name: "Remix", value: "remix", description: "Web standards" },
      { name: "Astro", value: "astro", description: "Content-first" },
    ],
  });

  const features = await checkbox({
    message: "Features:",
    choices: [
      { name: "TypeScript", value: "ts", checked: true },
      { name: "ESLint", value: "eslint", checked: true },
      { name: "Tailwind", value: "tailwind" },
      { name: "Vitest", value: "vitest" },
      { name: "CI/CD", value: "ci" },
    ],
  });

  const ok = await confirm({
    message: `Create ${name} with ${framework}?`,
    default: true,
  });

  if (ok) {
    console.log("Creating...", { name, framework, features });
  }
}

setup();
CLI/DevOpstypescript

Progress Bar for Long Tasks

Show a progress bar during long-running CLI operations using cli-progress.

import cliProgress from "cli-progress";

async function processFiles(files: string[]) {
  const bar = new cliProgress.SingleBar({
    format: " {bar} {percentage}% | {value}/{total} | ETA: {eta}s",
    barCompleteChar: "\u2588",
    barIncompleteChar: "\u2591",
    hideCursor: true,
  });

  bar.start(files.length, 0);
  for (const file of files) {
    await processFile(file);
    bar.increment();
  }
  bar.stop();
  console.log("Done!");
}

// Multi-bar for parallel work
async function parallelDownload(urls: string[]) {
  const multi = new cliProgress.MultiBar({
    format: " {name} | {bar} | {percentage}%",
    clearOnComplete: false,
  });

  const tasks = urls.map((url, i) => {
    const bar = multi.create(100, 0, { name: `File ${i + 1}` });
    return download(url, (pct: number) => bar.update(pct));
  });

  await Promise.all(tasks);
  multi.stop();
}

// Simple spinner
function spinner(msg: string) {
  const frames = ["-", "\\", "|", "/"];
  let i = 0;
  const id = setInterval(() => {
    process.stdout.write(`\r${frames[i++ % 4]} ${msg}`);
  }, 100);
  return {
    stop: (final: string) => { clearInterval(id); process.stdout.write(`\r${final}\n`); },
  };
}
CLI/DevOpstypescript

File Watcher with Debounce

Watch files for changes with debounced callbacks. Prevents duplicate triggers during rapid saves.

import { watch } from "chokidar";

function createWatcher(
  patterns: string[],
  callback: (paths: string[]) => void,
  debounceMs = 300
) {
  let timer: NodeJS.Timeout | null = null;
  let pending = new Set<string>();

  const flush = () => {
    const paths = Array.from(pending);
    pending = new Set();
    if (paths.length > 0) callback(paths);
  };

  const enqueue = (path: string) => {
    pending.add(path);
    if (timer) clearTimeout(timer);
    timer = setTimeout(flush, debounceMs);
  };

  const watcher = watch(patterns, {
    ignored: ["**/node_modules/**", "**/.git/**", "**/dist/**"],
    persistent: true,
    ignoreInitial: true,
  });

  watcher.on("change", enqueue).on("add", enqueue).on("unlink", enqueue);
  watcher.on("ready", () => console.log("Watching..."));

  return watcher;
}

// Usage
const w = createWatcher(
  ["src/**/*.ts", "src/**/*.tsx"],
  (files) => {
    console.log("Changed:", files);
    // rebuild, retest, etc.
  },
  200
);

process.on("SIGINT", () => { w.close(); process.exit(0); });
CLI/DevOpstypescript

GitHub API: Create PR

Create a pull request on GitHub using Octokit. Includes branch creation, file commits, and PR creation.

import { Octokit } from "@octokit/rest";

const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });

async function createPR(opts: {
  owner: string; repo: string; title: string; body: string;
  head: string; base?: string;
  files: { path: string; content: string }[];
}) {
  const { owner, repo, title, body, head, base = "main", files } = opts;

  // Get base SHA
  const { data: ref } = await octokit.git.getRef({ owner, repo, ref: `heads/${base}` });
  const sha = ref.object.sha;

  // Create branch
  await octokit.git.createRef({ owner, repo, ref: `refs/heads/${head}`, sha });

  // Create file blobs
  const blobs = await Promise.all(files.map((f) =>
    octokit.git.createBlob({
      owner, repo,
      content: Buffer.from(f.content).toString("base64"),
      encoding: "base64",
    }).then((r) => ({ path: f.path, sha: r.data.sha }))
  ));

  // Create tree + commit
  const { data: tree } = await octokit.git.createTree({
    owner, repo, base_tree: sha,
    tree: blobs.map((b) => ({
      path: b.path, mode: "100644" as const, type: "blob" as const, sha: b.sha,
    })),
  });

  const { data: commit } = await octokit.git.createCommit({
    owner, repo, message: title, tree: tree.sha, parents: [sha],
  });

  await octokit.git.updateRef({ owner, repo, ref: `heads/${head}`, sha: commit.sha });

  const { data: pr } = await octokit.pulls.create({ owner, repo, title, body, head, base });
  console.log(`PR: ${pr.html_url}`);
  return pr;
}
CLI/DevOpstypescript

Docker Compose for Dev Stack

Generate a Docker Compose file for Postgres, Redis, and a Next.js app with health checks.

import { writeFileSync } from "fs";

const compose = `services:
  db:
    image: postgres:16-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: devuser
      POSTGRES_PASSWORD: devpass
      POSTGRES_DB: myapp
    ports: ["5432:5432"]
    volumes: [pgdata:/var/lib/postgresql/data]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U devuser -d myapp"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    ports: ["6379:6379"]
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 5s
      retries: 5

  app:
    build: { context: ., dockerfile: Dockerfile }
    restart: unless-stopped
    ports: ["3000:3000"]
    environment:
      DATABASE_URL: postgresql://devuser:devpass@db:5432/myapp
      REDIS_URL: redis://redis:6379
      NODE_ENV: development
    depends_on:
      db: { condition: service_healthy }
      redis: { condition: service_healthy }
    volumes: [./src:/app/src]

volumes:
  pgdata:`;

writeFileSync("docker-compose.yml", compose);
console.log("Created docker-compose.yml");
console.log("Run: docker compose up -d");
CLI/DevOpstypescript

GitHub Actions: Test + Deploy

Generate a CI/CD workflow with lint, type check, tests, build, and deploy steps.

import { mkdirSync, writeFileSync } from "fs";

const yml = `name: CI/CD
on:
  push: { branches: [main] }
  pull_request: { branches: [main] }

concurrency:
  group: ci-\${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 22, cache: npm }
      - run: npm ci
      - run: npm run lint
      - run: npx tsc --noEmit
      - run: npm test -- --coverage
      - run: npm run build
      - uses: actions/upload-artifact@v4
        if: always()
        with: { name: coverage, path: coverage/ }

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy
        run: |
          curl -X POST "\${{ secrets.DEPLOY_WEBHOOK }}" \\
            -H "Authorization: Bearer \${{ secrets.DEPLOY_TOKEN }}"`;

mkdirSync(".github/workflows", { recursive: true });
writeFileSync(".github/workflows/ci.yml", yml);
console.log("Created .github/workflows/ci.yml");
CLI/DevOpstypescript

Cron Expression Parser

Parse cron expressions into human-readable descriptions. No external dependencies.

function describeCron(expr: string): string {
  const [minute, hour, dom, month, dow] = expr.trim().split(/\s+/);
  if (!minute || !hour || !dom || !month || !dow) {
    throw new Error("Invalid cron: need 5 fields");
  }

  const parts: string[] = [];

  if (minute === "*" && hour === "*") parts.push("Every minute");
  else if (minute.startsWith("*/")) parts.push(`Every ${minute.slice(2)} minutes`);
  else if (hour === "*") parts.push(`At minute ${minute} of every hour`);
  else parts.push(`At ${hour.padStart(2, "0")}:${minute.padStart(2, "0")}`);

  if (dow !== "*") {
    const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
    const names = dow.split(",").map((d) => {
      if (d.includes("-")) {
        const [a, b] = d.split("-").map(Number);
        return `${days[a]}-${days[b]}`;
      }
      return days[Number(d)] ?? d;
    });
    parts.push(`on ${names.join(", ")}`);
  }

  if (dom !== "*") parts.push(`on day ${dom}`);
  if (month !== "*") {
    const months = ["", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    parts.push(`in ${month.split(",").map((m) => months[Number(m)] ?? m).join(", ")}`);
  }

  return parts.join(" ");
}

console.log(describeCron("0 9 * * 1-5"));  // At 09:00 on Mon-Fri
console.log(describeCron("*/15 * * * *"));  // Every 15 minutes
console.log(describeCron("0 0 1 * *"));     // At 00:00 on day 1
console.log(describeCron("30 14 * * 0"));   // At 14:30 on Sun
CLI/DevOpstypescript

Webhook Receiver with Signature Verification

Verify HMAC webhook signatures. Works with GitHub, Stripe, and any HMAC-based provider.

import { createHmac, timingSafeEqual } from "crypto";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

function verifySignature(
  payload: string | Buffer,
  signature: string,
  secret: string,
  prefix = "sha256="
): boolean {
  const expected = prefix + createHmac("sha256", secret)
    .update(payload)
    .digest("hex");

  try {
    return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  } catch {
    return false;
  }
}

// app/api/webhook/route.ts
export async function POST(request: NextRequest) {
  const body = await request.text();
  const sig = request.headers.get("x-hub-signature-256");

  if (!sig) {
    return NextResponse.json({ error: "Missing signature" }, { status: 401 });
  }

  if (!verifySignature(body, sig, process.env.WEBHOOK_SECRET!)) {
    return NextResponse.json({ error: "Invalid signature" }, { status: 403 });
  }

  const event = JSON.parse(body);

  switch (event.action) {
    case "opened":
      console.log("PR opened:", event.pull_request?.title);
      break;
    case "closed":
      console.log("PR closed:", event.pull_request?.title);
      break;
    default:
      console.log("Event:", event.action);
  }

  return NextResponse.json({ received: true });
}
CLI/DevOpstypescript

Environment Variable Validator

Validate environment variables at startup with Zod. Fails fast with clear messages.

import { z } from "zod";

const envSchema = z.object({
  DATABASE_URL: z.string().url("Must be a valid URL"),
  OPENAI_API_KEY: z.string().startsWith("sk-", "Must start with sk-"),
  CLERK_SECRET_KEY: z.string().min(1, "Required"),
  WEBHOOK_SECRET: z.string().min(16, "Min 16 characters"),

  PORT: z.coerce.number().default(3000),
  NODE_ENV: z.enum(["development", "production", "test"]).default("development"),
  LOG_LEVEL: z.enum(["debug", "info", "warn", "error"]).default("info"),

  NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().startsWith("pk_"),
  NEXT_PUBLIC_APP_URL: z.string().url().default("http://localhost:3000"),
});

type Env = z.infer<typeof envSchema>;

function validateEnv(): Env {
  const result = envSchema.safeParse(process.env);

  if (!result.success) {
    console.error("\n  Environment validation failed:\n");
    for (const [key, msgs] of Object.entries(result.error.flatten().fieldErrors)) {
      console.error(`    ${key}: ${msgs?.join(", ")}`);
    }
    console.error("\n  Check your .env.local file.\n");
    process.exit(1);
  }

  return result.data;
}

export const env = validateEnv();

// Usage: import { env } from "@/lib/env";
// connect(env.DATABASE_URL); // string
// listen(env.PORT);          // number
AI Development Stack

Get Smarter About AI Dev

New tutorials, open-source projects, and deep dives on coding agents - delivered weekly.

One email per weekReal code, not theoryFree forever