# @js-fns/coerce

> Lightweight type coercion library

Latest version **0.1.0** (published 2026-09-23) · MIT license · 0 weekly downloads

## Install

```sh
npm install @js-fns/coerce
pnpm add @js-fns/coerce
yarn add @js-fns/coerce
bun add @js-fns/coerce
```

## Health

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

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

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.1.0 |
| Published | 2026-09-23 |
| First published | 2026-09-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 33.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 9 |
| Author | Sasha Koss <koss@nocorp.me> |
| Maintainers | kossnocorp |

## Links

- npm: https://www.npmjs.com/package/@js-fns/coerce
- Repository: https://github.com/js-fns/js-fns
- npm.io page: https://npm.io/package/@js-fns/coerce

## Recent versions

- 0.1.0 (latest) — 2026-09-23

## README

# @js-fns/coerce

@js-fns/coerce is a lightweight, near-zero overhead alternative to [Zod](https://zod.dev/) and [Valibot](https://valibot.dev/).

Unlike these libraries, @js-fns/coerce focuses on a single task: ensuring the data corresponds to the types.

It uses built-in JavaScript features to coerce whatever you pass to it, keeping the library small and fast.

```ts
import { coercer } from "@js-fns/coerce";

interface User {
  name: string;
  email: string;
  age?: number;
}

const coerceUser = coercer<User>(($) => ({
  name: String,
  email: String,
  age: $.Optional(Number),
}));

const user = coerceUser({ name: "Sasha", age: "37" });
//=> { name: "Sasha", email: "", age: 37 }
```

It accepts the desired shape type as the generic argument and type-checks the defined schema against it.

But just like the alternatives, it allows inferring types from the schema:

```ts
import { coercer } from "@js-fns/coerce";

const coerceUser = coercer.infer(($) => ({
  name: String,
  email: String,
  age: $.Optional(Number),
}));

type User = coercer.Infer<typeof coerceUser>;
// { name: string, email: string, age?: number }
```

It also accepts [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) making it ideal when working with forms, especially inside of React Server Components:

```tsx
import { coercer } from "@js-fns/coerce";

const coerceForm = coercer({
  email: String,
  password: String,
});

function SignInForm() {
  return (
    <form
      action={async (formData) => {
        "use server";
        const form = coerceForm(formData);
        await signIn(form);
      }}
    >
      <input name="email" type="email" required placeholder="Email" />
      <input name="password" type="password" required placeholder="Password" />
      <button>Sign in</button>
    </form>
  );
}
```

You can also use constructors as coercers, that is useful, for example, when working with `File`:

```tsx
import { coercer } from "@js-fns/coerce";

const coerceFile = coercer({
  file: File,
});

function UploadForm() {
  return (
    <form
      action={async (formData) => {
        "use server";
        const form = coerceFile(formData);
        await upload(form);
      }}
    >
      <input name="file" type="file" required />
      <button>Upload</button>
    </form>
  );
}
```

It will check if the value is an instance of `File`, and if not, it will try to call `new File()` without parameters.

## Getting Started

### Installation

The package is available as a standalone npm package:

```sh
npm install @js-fns/coerce
```

It is also available as a part of the `js-fns` collection:

```sh
npm install js-fns
```

## Changelog

See [the changelog](./CHANGELOG.md).

## License

[MIT © Sasha Koss](https://koss.nocorp.me/mit/)

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