Skip to content
Skillv1.0.0

exa-local-dev-loop

Configure Exa local development with hot reload, testing, and mock responses. Use when setting up a development environment, writing tests against Exa, or establishing a fast iteration cycle. Trigger

by jeremylongshore(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from jeremylongshore/tons-of-skills-marketplace (skills/.curated/exa-local-dev-loop/SKILL.md). Install upstream with npx skills add jeremylongshore/tons-of-skills-marketplace --skill exa-local-dev-loop. Copyright stays with the author (MIT).

Exa Local Dev Loop

Output

  • A small reviewed local Exa integration change with focused tests and normal source-control rollback.
  • A redacted development verification receipt using sanitized queries and scoped credentials.

Overview

Set up a fast, reproducible local development workflow for Exa integrations. Covers project structure, mock responses for unit tests, integration test patterns, and hot-reload configuration.

Prerequisites

  • exa-js installed and EXA_API_KEY configured
  • Node.js 18+ with npm/pnpm
  • vitest for testing (or jest)

Instructions

Step 1: Project Structure

my-exa-project/
├── src/
│   ├── exa/
│   │   ├── client.ts       # Singleton Exa client
│   │   ├── search.ts       # Search wrappers
│   │   └── types.ts        # Typed interfaces
│   └── index.ts
├── tests/
│   ├── exa.unit.test.ts    # Mock-based unit tests
│   └── exa.integration.test.ts  # Real API tests (needs key)
├── .env.local              # Local secrets (git-ignored)
├── .env.example            # Template for team
├── tsconfig.json
├── vitest.config.ts
└── package.json

Step 2: Package Setup

{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "test": "vitest",
    "test:unit": "vitest --testPathPattern=unit",
    "test:integration": "vitest --testPathPattern=integration",
    "build": "tsc"
  },
  "dependencies": {
    "exa-js": "^1.0.0"
  },
  "devDependencies": {
    "tsx": "^4.0.0",
    "vitest": "^2.0.0",
    "typescript": "^5.0.0"
  }
}

Step 3: Mock Exa for Unit Tests

// tests/exa.unit.test.ts
import { describe, it, expect, vi, beforeEach } from "vitest";

// Mock the exa-js module
vi.mock("exa-js", () => {
  return {
    default: vi.fn().mockImplementation(() => ({
      search: vi.fn().mockResolvedValue({
        results: [
          { url: "https://example.com/1", title: "Test Result 1", score: 0.95 },
          { url: "https://example.com/2", title: "Test Result 2", score: 0.87 },
        ],
      }),
      searchAndContents: vi.fn().mockResolvedValue({
        results: [
          {
            url: "https://example.com/1",
            title: "Test Result 1",
            score: 0.95,
            text: "This is the full text content of the page.",
            highlights: ["Key excerpt from the page"],
            summary: "A summary of the page content.",
          },
        ],
      }),
      findSimilar: vi.fn().mockResolvedValue({
        results: [
          { url: "https://similar.com/1", title: "Similar Page", score: 0.82 },
        ],
      }),
      getContents: vi.fn().mockResolvedValue({
        results: [
          { url: "https://example.com/1", title: "Page", text: "Content" },
        ],
      }),
    })),
  };
});

import Exa from "exa-js";

describe("Exa Search", () => {
  let exa: any;

  beforeEach(() => {
    exa = new Exa("test-key");
  });

  it("should return search results", async () => {
    const result = await exa.search("test query", { numResults: 5 });
    expect(result.results).toHaveLength(2);
    expect(result.results[0].score).toBeGreaterThan(0.9);
  });

  it("should return content with searchAndContents", async () => {
    const result = await exa.searchAndContents("test", { text: true });
    expect(result.results[0].text).toBeDefined();
    expect(result.results[0].highlights).toHaveLength(1);
  });
});

Step 4: Integration Tests (Real API)

// tests/exa.integration.test.ts
import { describe, it, expect } from "vitest";
import Exa from "exa-js";

// Skip if no API key available (CI without secrets)
const describeWithKey = process.env.EXA_API_KEY
  ? describe
  : describe.skip;

describeWithKey("Exa Integration", () => {
  const exa = new Exa(process.env.EXA_API_KEY!);

  it("should execute a basic search", async () => {
    const result = await exa.search("test connectivity", { numResults: 1 });
    expect(result.results.length).toBeGreaterThanOrEqual(1);
    expect(result.results[0].url).toMatch(/^https?:\/\//);
  }, 10000); // 10s timeout for API calls

  it("should return text content", async () => {
    const result = await exa.searchAndContents("TypeScript tutorial", {
      numResults: 1,
      text: { maxCharacters: 500 },
    });
    expect(result.results[0].text).toBeDefined();
    expect(result.results[0].text!.length).toBeGreaterThan(0);
  }, 15000);

  it("should find similar pages", async () => {
    const result = await exa.findSimilar("https://nodejs.org", {
      numResults: 3,
    });
    expect(result.results.length).toBeGreaterThanOrEqual(1);
  }, 10000);
});

Step 5: Environment Configuration

set -euo pipefail
# Create .env.example template (commit this)
cat > .env.example << 'EOF'
# Exa API — get key at https://dashboard.exa.ai
EXA_API_KEY=
EOF

# Create local env (git-ignored)
cp .env.example .env.local
echo "EXA_API_KEY=your-key-here" > .env.local

Error Handling

Error Cause Solution
Cannot find module 'exa-js' Not installed Run npm install exa-js
Test timeout Slow API response Increase vitest timeout to 15000ms
Mock not applied Import order issue Ensure vi.mock() is before imports
Integration test fails in CI No API key secret Add EXA_API_KEY to CI secrets or skip

Examples

Vitest Config for Exa Projects

// vitest.config.ts
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    globals: true,
    environment: "node",
    testTimeout: 15000,   // Exa API calls can take a few seconds
    setupFiles: ["dotenv/config"],
  },
});

Resources

Next Steps

See exa-sdk-patterns for production-ready code patterns.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/jeremylongshore-tons-of-skills-marketplace-exa-local-dev-loop/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

jeremylongshore-tons-of-skills-marketplace-exa-local-dev-loop.ocm.jsonjson
{
  "ocm": "1",
  "id": "jeremylongshore-tons-of-skills-marketplace-exa-local-dev-loop",
  "kind": "skill",
  "name": "exa-local-dev-loop",
  "description": "Configure Exa local development with hot reload, testing, and mock responses. Use when setting up a development environment, writing tests against Exa, or establishing a fast iteration cycle. Trigger with phrases like \"exa dev setup\", \"exa local development\", \"exa test setup\", \"develop with exa\", \"mock exa\".",
  "publisher": "jeremylongshore",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "coding"
    ],
    "tags": [
      "skill-md",
      "saas",
      "exa",
      "testing",
      "development",
      "skills-sh"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Configure Exa local development with hot reload, testing, and mock responses. Use when setting up a development environment, writing tests against Exa, or establishing a fast iteration cycle. Trigger with phrases like \"exa dev setup\", \"exa local development\", \"exa test setup\", \"develop with exa\", \"mock exa\"."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "skills.sh",
      "repository": "https://github.com/jeremylongshore/tons-of-skills-marketplace",
      "path": "skills/.curated/exa-local-dev-loop/SKILL.md",
      "ref": "HEAD",
      "url": "https://github.com/jeremylongshore/tons-of-skills-marketplace/blob/HEAD/skills/.curated/exa-local-dev-loop/SKILL.md",
      "key": "jeremylongshore/tons-of-skills-marketplace/skills/.curated/exa-local-dev-loop/SKILL.md"
    },
    "compatibility": "Designed for Claude Code",
    "allowed_tools": [
      "Read,",
      "Write,",
      "Edit,",
      "Bash(npm:*),",
      "Bash(pnpm:*),",
      "Bash(npx:*),",
      "Grep"
    ],
    "license": "MIT"
  },
  "instructions": "# Exa Local Dev Loop\n\n## Output\n\n- A small reviewed local Exa integration change with focused tests and normal source-control rollback.\n- A redacted development verification receipt using sanitized queries and scoped credentials.\n\n## Overview\n\nSet up a fast, reproducible local development workflow for Exa integrations. Covers project structure, mock responses for unit tests, integration test patterns, and hot-reload configuration.\n\n## Prerequisites\n\n- `exa-js` installed and `EXA_API_KEY` configured\n- Node.js 18+ with npm/pnpm\n- `vitest` for testing (or `jest`)\n\n## Instructions\n\n### Step 1: Pro",
  "cost": {
    "context_tokens": 1475
  }
}

Fetch it by URL: GET /api/v1/registry/jeremylongshore-tons-of-skills-marketplace-exa-local-dev-loop/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.