---
title: "Coming from Remeda"
description: "Swap remeda for @vinicunca/perkakas, rename purry to curry, and pick up the extras Perkakas ships."
canonical_url: "https://vinicunca.dev/perkakas/migrate/remeda"
---
# Coming from Remeda

> Swap remeda for @vinicunca/perkakas, rename purry to curry, and pick up the extras Perkakas ships.

Perkakas tracks Remeda's function set. A typical move is an install swap, an import rename, and `purry` → [`curry`](https://vinicunca.dev/perkakas/functions#curry).

## Install

Replace `remeda` with `@vinicunca/perkakas`.

```bash [pnpm]
pnpm remove remeda
pnpm add @vinicunca/perkakas
```

```bash [npm]
npm uninstall remeda
npm install @vinicunca/perkakas
```

```bash [yarn]
yarn remove remeda
yarn add @vinicunca/perkakas
```

```bash [bun]
bun remove remeda
bun add @vinicunca/perkakas
```

## Imports

```ts
// Perkakas
import { curry, filter, map, pipe } from '@vinicunca/perkakas';
// Remeda
import { filter, map, pipe, purry } from 'remeda';
```

You can keep importing individual helpers. There is no default export.

## `purry` is `curry`

[`curry`](https://vinicunca.dev/perkakas/functions#curry) is Remeda's `purry`: it builds the data-first / data-last pair most Perkakas functions use. It is not type-safe on its own — wrap it with your own overloads, the way the library does.

```ts
import { curry } from '@vinicunca/perkakas';

function findIndex<T>(array: Array<T>, fn: (item: T) => boolean): number;
function findIndex<T>(fn: (item: T) => boolean): (array: Array<T>) => number;
function findIndex(...args: ReadonlyArray<unknown>): unknown {
  return curry(findIndexImplementation, args);
}
```

## Perkakas-only exports

These are not in Remeda. One-line descriptions below match the JSDoc (or the source, when JSDoc is missing).

| Export | What it does |
| --- | --- |
| [`curry`](https://vinicunca.dev/perkakas/functions#curry) | Remeda's `purry`: build data-first and data-last signatures. |
| [`humanReadableFileSize`](https://vinicunca.dev/perkakas/functions#humanReadableFileSize) | Format a byte count as a human-readable size (`1.0 kB`, `2.0 MiB`). |
| [`sleep`](https://vinicunca.dev/perkakas/functions#sleep) | Return a promise that resolves after a given number of milliseconds. |
| [`slugify`](https://vinicunca.dev/perkakas/functions#slugify) | Turn a string into a URL/DOM-safe slug. |
| [`KEY_CODES`](https://vinicunca.dev/perkakas/functions#KEY_CODES) | Keyboard `event.code` name constants (`ENTER`, `ESC`, …). |
| [`isBrowser`](https://vinicunca.dev/perkakas/functions#isBrowser) | `true` when `window` is defined. |
| [`DeepPartial`](https://vinicunca.dev/perkakas/functions#DeepPartial) | Recursive `Partial<T>`, exported from `type.helpers`. |

`KEY_CODES`, `isBrowser`, and `DeepPartial` have no `@category` tag in source, so they land under **Other** on the [Functions](https://vinicunca.dev/perkakas/functions) page.


## Sitemap

See the full [sitemap](https://vinicunca.dev/sitemap.md) for all pages.
