# @toad-contracts/valibot

Latest version **1.0.0** (published 2026-09-19) · MIT license · 0 weekly downloads

## Install

```sh
npm install @toad-contracts/valibot
pnpm add @toad-contracts/valibot
yarn add @toad-contracts/valibot
bun add @toad-contracts/valibot
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-09-19 |
| First published | 2026-06-26 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 9.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 0 |
| Maintainers | kibertoad |
| Keywords | api, backend, contract, contracts, frontend, single, source, standard-schema, truth, valibot |

## Links

- npm: https://www.npmjs.com/package/@toad-contracts/valibot
- Repository: https://github.com/kibertoad/toad-contracts
- npm.io page: https://npm.io/package/@toad-contracts/valibot

## Dependencies (1)

- [@toad-contracts/core](https://npm.io/package/@toad-contracts/core.md) 1.0.0

## Alternatives

- [jsforce](https://npm.io/package/jsforce.md) — 851.2K weekly downloads
- [react-native-qrcode-svg](https://npm.io/package/react-native-qrcode-svg.md) — 693.5K weekly downloads
- [@salesforce/plugin-data](https://npm.io/package/@salesforce/plugin-data.md) — 394.9K weekly downloads
- [@backstage/plugin-search-common](https://npm.io/package/@backstage/plugin-search-common.md) — 308.5K weekly downloads
- [@chain-registry/types](https://npm.io/package/@chain-registry/types.md) — 38.4K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2026-09-19
- 0.5.0 — 2026-06-27
- 0.4.0 — 2026-06-27
- 0.3.1 — 2026-06-27
- 0.1.0 — 2026-06-26

## README

# @toad-contracts/valibot

The [valibot](https://valibot.dev) adapter for [`@toad-contracts/core`](../core).

The core contract library is written against the vendor-neutral
[Standard Schema](https://github.com/standard-schema/spec) interface, which valibot v1 implements.
This package re-exports the entire core API and adds `withObjectKeys`, the valibot implementation of
the single object-key introspection surface (`StandardObjectKeysV1`) that API contracts need for
path-param schemas and message contracts need for field introspection, something the Standard Schema
interface does not expose.

`valibot` is a peer dependency.

```sh
pnpm add @toad-contracts/valibot valibot
```

## Usage

Import everything from `@toad-contracts/valibot`. The full core surface (`defineApiContract`,
response factories, inference types, client types, and more) is re-exported unchanged. See the
[`@toad-contracts/core` README](../core/README.md) for the complete reference.

```ts
import {
  defineApiContract,
  mapApiContractToPath,
  describeApiContract,
  withObjectKeys,
} from "@toad-contracts/valibot";
import { object, string } from "valibot";

const getUser = defineApiContract({
  method: "get",
  requestPathParamsSchema: withObjectKeys(object({ userId: string() })),
  pathResolver: ({ userId }) => `/users/${userId}`,
  responsesByStatusCode: {
    200: object({ id: string(), name: string() }),
  },
});

mapApiContractToPath(getUser); // "/users/:userId"
describeApiContract(getUser); // "GET /users/:userId"
```

## What this package adds

`withObjectKeys(schema)` is the only addition; everything else is a direct re-export from
`@toad-contracts/core`.

API contracts need a `requestPathParamsSchema` to expose its object keys to build the route path, and
message contracts need a schema's declared field names for routing/projection — both read through the
same `StandardObjectKeysV1` surface, which the Standard Schema interface does not provide.
`withObjectKeys` attaches that capability to a valibot object schema by reading its `.entries`:

```ts
// effectively:
export const withObjectKeys = (schema) => {
  const keys = Object.keys(schema.entries);
  Object.assign(schema["~standard"], {
    objectKeys: { input: () => keys, output: () => keys },
  });
  return schema;
};
```

Wrap any path-param or message schema with it. Only plain object schemas (`object`, `strictObject`,
`looseObject`, `objectWithRest`) expose `.entries`; a wrapped schema such as `pipe(object(...), ...)`
or a non-object schema does not, so `withObjectKeys` throws an actionable `TypeError` rather than
silently producing a schema with no object keys.

The path-mapping helpers `mapApiContractToPath(contract)` and `describeApiContract(contract)` are
re-exported from core unchanged and already single-argument; they read the keys through whatever
`withObjectKeys` attached. The same wrapper makes a schema satisfy
[`@toad-contracts/messages`](../messages)' `RoutableMessageSchema`, so a routing container can
enumerate a message's declared field names — no separate message-specific helper is needed:

```ts
import { withObjectKeys } from "@toad-contracts/valibot";
import { literal, object, string } from "valibot";

const schema = withObjectKeys(object({ type: literal("user.created"), id: string() }));
schema["~standard"].objectKeys.input(); // ["type", "id"]
```

---
_Source: https://npm.io/package/@toad-contracts/valibot · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
