---
title: Pipelines
description: >-
  For detailed validations and transformations, a schema can be wrapped in a
  pipeline. This is useful to validate further details apart from the raw data
  type.
contributors:
  - fabian-hiller
  - EltonLobo07
  - BastiDood
  - morinokami
  - jasperteo
  - daxeh
  - ariskemper
---

import { ApiList, Link } from '~/components';

# Pipelines

For detailed validations and transformations, a schema can be wrapped in a pipeline. Especially for schema functions like <Link href="/api/string/">`string`</Link>, <Link href="/api/number/">`number`</Link>, <Link href="/api/date/">`date`</Link>, <Link href="/api/object/">`object`</Link>, and <Link href="/api/array/">`array`</Link>, this feature is useful for validating properties beyond the raw data type.

## How it works

In simple words, a pipeline is a list of schemas and actions that synchronously passes through the input data. It must always start with a schema, followed by up to 19 schemas or actions. Each schema and action can examine and modify the input. The pipeline is therefore perfect for detailed validations and transformations.

### Example

For example, the pipeline feature can be used to trim a string and make sure that it is an email that ends with a specific domain.

```ts
import * as v from 'valibot';

const EmailSchema = v.pipe(
  v.string(),
  v.trim(),
  v.email(),
  v.endsWith('@example.com')
);
```

## Validations

Pipeline validation actions examine the input and, if the input does not meet a certain condition, return an issue. If the input is valid, it is returned as the output and, if present, picked up by the next action in the pipeline.

> Whenever possible, pipelines are run completely, even if an issue has occurred, to collect all possible issues. If you want to abort the pipeline early after the first issue, you need to set the `abortPipeEarly` option to `true`. Learn more about <Link href="/guides/parse-data/#configuration">parsing configuration</Link>, or use the <Link href="/api/config/">`config`</Link> method for more granular control over individual pipelines.

<ApiList
  label="Validation actions"
  items={[
    'base64',
    'bic',
    'bytes',
    'check',
    'checkItems',
    'creditCard',
    'cuid2',
    'decimal',
    'digits',
    'domain',
    'email',
    'emoji',
    'empty',
    'endsWith',
    'entries',
    'everyItem',
    'excludes',
    'finite',
    'graphemes',
    'gtValue',
    'hash',
    'hexadecimal',
    'hexColor',
    'includes',
    'integer',
    'ip',
    'ipv4',
    'ipv6',
    'isbn',
    'isrc',
    'isoDate',
    'isoDateTime',
    'isoDateTimeSecond',
    'isoTime',
    'isoTimeSecond',
    'isoTimestamp',
    'isoWeek',
    'ksuid',
    'length',
    'ltValue',
    'mac',
    'mac48',
    'mac64',
    'maxBytes',
    'maxEntries',
    'maxGraphemes',
    'maxLength',
    'maxSize',
    'maxValue',
    'maxWords',
    'mimeType',
    'minBytes',
    'minEntries',
    'minGraphemes',
    'minLength',
    'minSize',
    'minValue',
    'minWords',
    'multipleOf',
    'nanoid',
    'nonEmpty',
    'notBytes',
    'notEntries',
    'notGraphemes',
    'notLength',
    'notSize',
    'notValue',
    'notValues',
    'notWords',
    'octal',
    'parseJson',
    'partialCheck',
    'rawCheck',
    'regex',
    'rfcEmail',
    'safeInteger',
    'size',
    'slug',
    'someItem',
    'startsWith',
    'ulid',
    'url',
    'uuid',
    'value',
    'values',
    'words',
  ]}
/>

Some of these actions can be combined with different schemas. For example, <Link href="/api/minValue/">`minValue`</Link> can be used to validate the minimum value of <Link href="/api/string/">`string`</Link>, <Link href="/api/number/">`number`</Link>, <Link href="/api/bigint/">`bigint`</Link>, and <Link href="/api/date/">`date`</Link>.

```ts
import * as v from 'valibot';

const StringSchema = v.pipe(v.string(), v.minValue('foo'));
const NumberSchema = v.pipe(v.number(), v.minValue(1234));
const BigintSchema = v.pipe(v.bigint(), v.minValue(1234n));
const DateSchema = v.pipe(v.date(), v.minValue(new Date()));
```

### Custom validation

For custom validations, <Link href="/api/check/">`check`</Link> can be used. If the function passed as the first argument returns `false`, an issue is returned. Otherwise, the input is considered valid.

```ts
import * as v from 'valibot';
import { isValidUsername } from '~/utils';

const UsernameSchema = v.pipe(
  v.string(),
  v.check(isValidUsername, 'This username is invalid.')
);
```

> You can forward the issues of a pipeline validation to a child. See the <Link href="/guides/methods/#forward">methods</Link> guide for more information.

## Transformations

Pipeline transformation actions allow to change the value and data type of the input data. This can be useful for example to remove spaces at the beginning or end of a string or to force a minimum or maximum value.

<ApiList
  label="Transformation actions"
  items={[
    'brand',
    'filterItems',
    'findItem',
    'flavor',
    'guard',
    'mapItems',
    'rawTransform',
    'readonly',
    'reduceItems',
    'sortItems',
    'toBigint',
    'toBoolean',
    'toCamelCase',
    'toDate',
    'toKebabCase',
    'toLowerCase',
    'toMaxValue',
    'toMinValue',
    'toNumber',
    'toPascalCase',
    'toSnakeCase',
    'toString',
    'toUpperCase',
    'transform',
    'trim',
    'trimEnd',
    'trimStart',
  ]}
/>

For example, the pipeline of the following schema enforces a minimum value of 10. If the input is less than 10, it is replaced with the specified minimum value.

```ts
import * as v from 'valibot';

const NumberSchema = v.pipe(v.number(), v.toMinValue(10));
```

### Custom transformation

For custom transformations, <Link href="/api/transform/">`transform`</Link> can be used. The function passed as the first argument is called with the input data and the return value defines the output. The following transformation changes the output of the schema to `null` for any number less than 10.

```ts
import * as v from 'valibot';

const NumberSchema = v.pipe(
  v.number(),
  v.transform((input) => (input < 10 ? null : input))
);
```

## Metadata

In addition to the validation and transformation actions, a pipeline can also be used to add metadata to a schema. This can be useful when working with AI tools or for documentation purposes.

<ApiList
  label="Metadata actions"
  items={['description', 'metadata', 'title']}
/>

```ts
const UsernameSchema = v.pipe(
  v.string(),
  v.regex(/^[a-z0-9_-]{4,16}$/iu),
  v.title('Username'),
  v.description(
    'A username must be between 4 and 16 characters long and can only contain letters, numbers, underscores and hyphens.'
  )
);
```
