{"id":14041,"library":"specmatic","title":"Specmatic Node.js Wrapper","description":"Specmatic-node is an npm package that provides a Node.js wrapper for the core Specmatic executable JAR, enabling contract-driven development (CDD) workflows within JavaScript and TypeScript projects. It allows developers to easily install and manage the Specmatic JAR, run CLI commands, and programmatically interact with Specmatic's capabilities for API stubbing (smart mocks) and contract testing. The current stable version is 2.43.3. New patch and minor versions are released frequently, often several times a month, reflecting active development. Its key differentiators include enabling a 'no-code' approach to contract testing from OpenAPI/Swagger/AsyncAPI specifications and providing a smart stub server that can be configured programmatically to simulate API providers, facilitating independent development for API consumers. It bridges the JVM-based core Specmatic functionality with the Node.js ecosystem.","status":"active","version":"2.43.3","language":"javascript","source_language":"en","source_url":"https://github.com/specmatic/specmatic-node","tags":["javascript","contract","testing","specmatic","contract driven development","cdd","openapi","swagger","asyncapi","typescript"],"install":[{"cmd":"npm install specmatic","lang":"bash","label":"npm"},{"cmd":"yarn add specmatic","lang":"bash","label":"yarn"},{"cmd":"pnpm add specmatic","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Specmatic primarily uses named exports. Prefer ESM imports in modern Node.js environments.","wrong":"const { startHttpStub } = require('specmatic')","symbol":"startHttpStub","correct":"import { startHttpStub } from 'specmatic'"},{"note":"The `test` function for running contract tests is a named export, not a default export.","wrong":"import test from 'specmatic'","symbol":"test","correct":"import { test } from 'specmatic'"},{"note":"Use named imports for direct access to functions like `setHttpStubExpectationJson`.","wrong":"const setHttpStubExpectationJson = require('specmatic').setHttpStubExpectationJson","symbol":"setHttpStubExpectationJson","correct":"import { setHttpStubExpectationJson } from 'specmatic'"}],"quickstart":{"code":"import { startHttpStub, setHttpStubExpectationJson, test, stopHttpStub } from 'specmatic';\nimport path from 'path'; // For resolving specmatic directory\n\n// Define the directory where your Specmatic OpenAPI/contract specification files are located.\n// For example, if your specs are in 'src/specmatic', use path.resolve(__dirname, 'src', 'specmatic')\nconst specmaticDir = path.resolve(__dirname, 'specmatic'); // Adjust this path as needed\n\nasync function runSpecmaticWorkflow() {\n  let stub;\n  try {\n    console.log(`Attempting to start Specmatic Stub server with specs from: ${specmaticDir}`);\n    // Start the Specmatic stub server, binding it to localhost:9000\n    // The specmaticDir is passed as an argument to load contract specifications.\n    stub = await startHttpStub('localhost', 9000, [specmaticDir]);\n    console.log(`Specmatic Stub running successfully on ${stub.url} (Process ID: ${stub.pid})`);\n\n    // Define and set a programmatic expectation for a GET /greeting endpoint on the stub.\n    // This allows the stub to respond with a specific JSON body for a matching request.\n    const expectation = {\n      \"method\": \"GET\",\n      \"path\": \"/greeting\",\n      \"response\": {\n        \"status\": 200,\n        \"headers\": {\n          \"Content-Type\": \"application/json\"\n        },\n        \"body\": {\"message\": \"Hello from Specmatic Stub!\"}\n      }\n    };\n    await setHttpStubExpectationJson(expectation, `http://localhost:${stub.port}`);\n    console.log('Stub expectation set for GET /greeting.');\n\n    // Simulate an API client interaction by fetching from the stub.\n    // In a real scenario, your application's HTTP client would call this.\n    console.log('Fetching from stub: GET /greeting');\n    const stubResponse = await fetch(`http://localhost:${stub.port}/greeting`);\n    const stubData = await stubResponse.json();\n    console.log('Received response from stub:', stubData);\n\n    // Run contract tests. This typically involves Specmatic verifying your API\n    // implementation against its OpenAPI specifications. For this example,\n    // we are testing against the running stub itself, which should pass if the spec is valid.\n    console.log(`Running contract tests against ${stub.url}`);\n    const testResult = await test(`http://localhost:${stub.port}`, [specmaticDir]);\n    console.log('Contract Test Results:', JSON.stringify(testResult, null, 2));\n\n  } catch (error) {\n    console.error('Specmatic workflow failed:', error);\n    process.exit(1);\n  } finally {\n    // Crucially, stop the Specmatic stub server to release resources and terminate the JAR process.\n    if (stub && stub.pid) {\n      console.log(`Stopping Specmatic Stub server (PID: ${stub.pid})...`);\n      await stopHttpStub(stub.pid);\n      console.log('Specmatic Stub stopped.');\n    }\n  }\n}\n\n// Execute the Specmatic workflow\nrunSpecmaticWorkflow();","lang":"typescript","description":"Demonstrates how to programmatically start a Specmatic stub server, define and set dynamic expectations, simulate client interaction with the stub, run contract tests against it, and ensure the stub is properly shut down."},"warnings":[{"fix":"Set the environment variable `NODE_OPTIONS=--dns-result-order=ipv4first` before running your Node.js application, or consistently use `localhost` instead of `127.0.0.1` when specifying hostnames for Specmatic.","message":"Node.js versions 17/18 (and potentially others) may experience 'Connection Refused' errors when the Specmatic stub starts, often due to Node's default preference for IPv6 DNS resolution.","severity":"gotcha","affected_versions":">=2.x"},{"fix":"Ensure your execution environment is a Node.js context that provides `setImmediate` or include a polyfill for `setImmediate` if running in a non-standard Node.js setup (e.g., using `jest-environment-jsdom` without appropriate Node.js shims).","message":"The error 'ReferenceError: setImmediate is not defined' can occur when `specmatic-node` is run in certain environments that lack Node.js global APIs, such as some browser-like test runners or older Node.js versions.","severity":"gotcha","affected_versions":">=2.x"},{"fix":"Always call `stopHttpStub(stub.pid)` explicitly in your test teardown logic (e.g., `afterAll` hook in Jest) to ensure the Specmatic JAR process is cleanly shut down.","message":"The Specmatic stub (the underlying Java process) may not terminate automatically after test execution, leading to orphaned processes and potential port conflicts.","severity":"gotcha","affected_versions":">=2.x"}],"env_vars":null,"search_vec":"'2.43.3':68 'activ':83 'allow':35 'api':56,114,120 'approach':94 'asyncapi':145 'base':127 'bridg':123 'capabl':54 'cdd':27,142 'cli':46 'code':93 'command':47 'configur':110 'consum':121 'contract':24,61,96,136,139 'contract-driven':23 'core':18,128 'current':64 'develop':26,36,84,118,141 'differenti':87 'driven':25,140 'easili':38 'ecosystem':134 'enabl':22,89 'execut':20 'facilit':116 'frequent':76 'function':130 'includ':88 'independ':117 'instal':39 'interact':50 'jar':21,44 'javascript':30,135 'jvm':126 'jvm-base':125 'key':86 'manag':41 'minor':72 'mock':59 'month':81 'new':69 'no-cod':91 'node':6 'node.js':2,14,133 'npm':9 'often':77 'openapi':143 'openapi/swagger/asyncapi':99 'packag':10 'patch':70 'programmat':49,111 'project':33 'provid':12,102,115 'reflect':82 'releas':75 'run':45 'server':106 'sever':78 'simul':113 'smart':58,104 'specif':100 'specmat':1,5,19,43,52,129,138 'specmatic-nod':4 'stabl':65 'stub':57,105 'swagger':144 'test':62,97,137 'time':79 'typescript':32,146 'version':66,73 'within':29 'workflow':28 'wrapper':3,15","created_at":"2026-04-20T01:57:38.051595+00:00","updated_at":"2026-04-20T01:57:38.051595+00:00","problems":[{"fix":"Set `NODE_OPTIONS=--dns-result-order=ipv4first` in your shell or use `localhost` consistently instead of `127.0.0.1`.","cause":"Node.js DNS resolution order preferring IPv6 on some systems, causing issues when Specmatic binds to IPv4.","error":"Connection Refused error when connecting to stub"},{"fix":"Ensure a standard Node.js test environment is used, or polyfill `setImmediate` for compatibility.","cause":"Execution environment lacks the Node.js global `setImmediate` function, often in browser-mocking test setups.","error":"ReferenceError: setImmediate is not defined"}],"ecosystem":"npm","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"2.41.1","cli_name":"specmatic","cli_version":null,"type":"library","homepage":"https://specmatic.io","github":"https://github.com/specmatic/specmatic-node","docs":null,"changelog":null,"pypi":null,"npm":"https://www.npmjs.com/package/specmatic","openapi_spec":null,"status_page":null,"smithery":null,"categories":["testing","http-networking","web-framework"],"base_url":null,"auth_type":null,"provenance":{"verified_status":null,"verified_at":null,"last_verified":"2026-06-17","next_check":"2026-07-18","install_tag":null}}