Migrating from Specmatic Config v2 to v3
This guide explains why you should migrate from config version: 2 to version: 3, how v3 makes System Under Test and dependency configuration clearer, and what additional benefits you get from the v3 model.
Why move to v3
v3 is now the recommended format and provides a more explicit, service-centric model.
Main advantages:
- Clear separation of intent:
systemUnderTestdefines what you are validating, anddependencies.servicesdefines what you virtualize. - Less duplication:
componentslets you define reusable sources, services, and run options once, then reference them via$ref. - Better readability at scale:
Instead of large
providesandconsumeslists, each service has a named definition and run profile. - More structured runtime behavior:
Global controls are grouped under
specmatic.settingsand governance/reporting underspecmatic.governance. - Better extensibility:
components.adaptersand service-level run profiles make it easier to evolve usage across protocols and environments.
The key mindset shift
In v2, the model is contract-list-centric (provides/consumes).
In v3, the model is service-wiring-centric:
- Define reusable contract sources in
components.sources - Define named services in
components.services - Define how each service runs in
components.runOptions - Wire them into
systemUnderTestanddependencies
This makes configuration closer to your actual architecture.
SUT and dependency configuration is much clearer in v3
v2 (implicit role through provides/consumes)
version: 2
contracts:
- git:
url: https://github.com/specmatic/specmatic-order-contracts.git
provides:
- com/petstore/store.yaml
consumes:
- com/petstore/payment.yaml
v3 (explicit service wiring)
version: 3
systemUnderTest:
service:
$ref: "#/components/services/petStoreService"
runOptions:
$ref: "#/components/runOptions/petStoreTest"
dependencies:
services:
- service:
$ref: "#/components/services/paymentService"
runOptions:
$ref: "#/components/runOptions/paymentMock"
components:
sources:
centralContracts:
git:
url: https://github.com/specmatic/specmatic-order-contracts.git
services:
petStoreService:
definitions:
- definition:
source:
$ref: "#/components/sources/centralContracts"
specs:
- com/petstore/store.yaml
paymentService:
definitions:
- definition:
source:
$ref: "#/components/sources/centralContracts"
specs:
- com/petstore/payment.yaml
runOptions:
petStoreTest:
openapi:
type: test
baseUrl: http://localhost:8080
paymentMock:
openapi:
type: mock
baseUrl: http://localhost:8090
What is clearer now:
- SUT is explicit (
systemUnderTest) rather than inferred. - Dependencies are explicit (
dependencies.services) and can each carry their own run behavior. - Test vs mock mode is explicit per service in
runOptions(type: testortype: mock). - The same contract source can be reused across many services without repeating source details.
Field mapping cheat sheet (v2 -> v3)
contracts[*].git->components.sources.<name>.gitcontracts[*].provides->components.services.<sut>.definitions+systemUnderTest.servicecontracts[*].consumes->components.services.<dependency>.definitions+dependencies.services[*].serviceprovides[*].config/consumes[*].config->components.runOptions.<name>report->specmatic.governance.reportandspecmatic.governance.successCriteriatest/mocksettings ->specmatic.settingsand/or service-specificrunOptionshooks->components.adapters(where applicable)
Additional inferred benefits from the docs
- Better multi-protocol support:
runOptionscan be protocol-specific (OpenAPI, GraphQL, gRPC, AsyncAPI), while preserving one consistent top-level model. - Easier environment variation: Named run profiles can be switched without rewriting contract definitions.
- Cleaner governance and CI:
Coverage thresholds and report formats are centralized under
specmatic.governance. - Stronger long-term maintainability:
components+$refencourage modular configuration as service count grows.
Migration approach
- Run automatic upgrade:
specmatic config upgrade --input specmatic_old.yaml --output specmatic.yaml - Verify service intent:
Ensure exactly one primary
systemUnderTestis wired correctly. - Verify dependency wiring:
Each consumed contract should appear under
dependencies.serviceswith appropriate mock run options. - Consolidate repeated source/run settings:
Move duplicates into
componentsand reference them via$ref. - Run your normal test and mock flows: Confirm base URLs, protocol-specific options, and governance behavior are unchanged.
For command variants (Docker/Java/npm), see Upgrade Configuration.
Further reference
For deeper details on each section, see: