Skip to content

seampact 1.0.0

seampact 1.0.0 is the first release. You write one contract in YAML. seampact generates the server boundary, the client and the OpenAPI document from it, and checks in CI that nothing drifted.

Every package, in every ecosystem, has the same version. Install shows how to get each one.

Registry What you get Status
npm the CLI, the generators, the runtime and the packs live, 2026-11-07
Maven Central the Spring Boot runtime, the hooks, the Maven plugin and the compiler live, 2026-11-07
Gradle Plugin Portal the Gradle plugin io.github.jubasse.seampact pending review, 2026-11-07
Packagist seampact/laravel, seampact/symfony and their libraries live, 2026-11-07
PyPI seampact-fastapi, seampact-drf, seampact-ninja and their libraries live, 2026-11-07
GitHub releases the compiler binary for five systems, with SHA256SUMS live, 2026-11-07

The Gradle Plugin Portal reviews each new plugin by hand, which takes a few days. Until it approves, the Maven plugin works at once, and Gradle builds can load the plugin from Maven Central: see the Spring Boot guide.

On release day, pnpm can answer “no matching version” for @seampact/*. Its minimumReleaseAge setting holds back a package published in the last day. Wait, or add minimumReleaseAgeExclude: ["@seampact/*"] to pnpm-workspace.yaml: see Install.

Servers:

Clients and validators:

  • A typed fetch client, React hooks (TanStack Query, SWR or RTK Query) and TypeScript types.
  • Validators with zod, yup or class-validator.

Everything else:

  • The OpenAPI 3.1 document of each api.
  • seampact diff classifies a change as additive or breaking, and seampact check fails CI on drift.
  • Access rights, signed webhooks, idempotency keys, paging and conditional requests.
  • The standalone compiler binary: compile, lint, diff, explain and bundle without Node.js.

A form that 1.0 does not support is refused by name when you run seampact generate. The message says which form and where. Nothing is generated silently wrong. Each family has one table of codes, causes and fixes in Generate errors:

  • Clients: the fetch client, React, Vue, Angular and MSW.
  • Node servers: Express, Fastify, Hono, NestJS and AdonisJS.
  • Spring Boot.
  • PHP: Laravel and Symfony.
  • Python: FastAPI, DRF and Ninja.
  • Spring Boot, PHP and Python: forms all three refuse, such as scope ids read outside the path, nested input field rights and the handlers and naming options.
  • Every server: forms several servers refuse, such as sort keys restricted by a right, response headers written on an identity, and degradable operations.

Where a fix says “remove the operation”, list the other operations in the entry’s operations filter and write that one by hand.

Known differences between servers. A portable client avoids them:

  • A comma list sent as an empty value (sort=) is an empty list on the Node servers and one empty item on Spring Boot and PHP.
  • A comma key sent twice (sort=a&sort=-b) answers 400 on the Node servers. Spring Boot and PHP join both values.
  • limit=1e3 is read as 1000 on Node. Spring Boot, Laravel, Symfony and FastAPI answer 400.

Not in 1.0:

  • API Platform comes after 1.0. Use Symfony with its own controllers, as the Symfony guide shows.
  • The CASL (NestJS) and spatie (Laravel) adapters come in 1.1. Until then, write the rights in your own guard or policy.
  • Test helpers, dev docs served by the server, and a ready-made idempotency store are not generated on the Node, Java, PHP and Python servers. The idempotency store is an interface you implement; the Node servers have an in-memory one.
  • Express, Fastify, Hono and FastAPI generate no native access export, and Express, Fastify and Hono map no framework security refusals: your own middleware owns them.
  • The Angular service does not set HttpClient’s XSRF header. Call withXsrfConfiguration with the contract’s CSRF header name, as the Angular guide says.
  • The fetch client does not retry by the nature of an error code. It retries a rejected request, never a declared error.
  • The binary and the plugins download over HTTPS only and read no proxy variable. Behind a proxy, put the binary on a mirror and set its URL and hash, or point to a local file.
  • macOS binaries carry an ad hoc signature, not an Apple one. If macOS blocks the file, allow it in System Settings.