# Obfuscate a Remix app

There is no @afterpack/remix package. Remix builds through Vite, so use @afterpack/vite, or run the CLI on the build output.

Source: https://www.afterpack.dev/docs/frameworks/remix

> **No Remix-specific package**
>
> AfterPack does not publish `@afterpack/remix`. Remix v2 and React Router v7 build through Vite, so [the Vite plugin](https://www.afterpack.dev/docs/frameworks/vite) is the natural wiring, and [the CLI](https://www.afterpack.dev/docs/cli) works on the output regardless. [Frameworks](https://www.afterpack.dev/docs/frameworks) has the full matrix.

## Install

Remix's own plugin runs inside your `vite.config.ts`, so `@afterpack/vite` goes in the same `plugins` array, after it:

```bash
npm install -D @afterpack/vite
```

```ts
// vite.config.ts
import { defineConfig } from "vite";
import { vitePlugin as remix } from "@remix-run/dev";
import { afterpackVite } from "@afterpack/vite";

export default defineConfig({
  plugins: [remix(), afterpackVite()],
});
```

Or skip the package and run [the CLI](https://www.afterpack.dev/docs/cli) on the build output instead.

## Build

The plugin runs on `generateBundle`, obfuscating every JavaScript chunk in the bundle before Vite writes it. Remix builds the client and server legs as separate Vite builds, so the plugin runs once per leg, on that leg's bundle only. Pin one [`seed`](https://www.afterpack.dev/docs/config#seed) (`seed: "git"` is the simplest) if the two legs ship together and you want them built from the same seed. [Builds & CI](https://www.afterpack.dev/docs/builds) covers the trade.

Building with the CLI works the same way: build first, then point AfterPack at each output directory. A Remix Vite build typically writes `build/client` and `build/server`:

```bash
npx afterpack@latest build/client --seed=git
```

The [path argument is required](https://www.afterpack.dev/docs/cli#usage); there is no auto-detection. It takes a directory to walk, or a single `.js`/`.mjs`/`.cjs` file. Run it once per directory you want obfuscated, with the same [`--seed`](https://www.afterpack.dev/docs/config#seed) across both when they ship together. Both paths call the same shared pass, so everything else (the [preset ladder](https://www.afterpack.dev/docs/presets), the [fail-closed behavior](https://www.afterpack.dev/docs/diagnostics#fail-closed-no-exceptions), the [artifacts](https://www.afterpack.dev/docs/cli#files)) is identical.

## Verify

[Build mode](https://www.afterpack.dev/docs/config#build-mode) turns the [Protection Map](https://www.afterpack.dev/docs/protection-map) off by default under `NODE_ENV=production` or `CI=true`. Build with source maps on for the build you want to inspect, then open the gitignored `.afterpack/protectionMap.html`. It contains your full source. Never commit it or serve it.

## Options

Every [configuration key](https://www.afterpack.dev/docs/config) works the same way through this plugin as on the [Vite page](https://www.afterpack.dev/docs/frameworks/vite#options), including directive capture; see [Configuration](https://www.afterpack.dev/docs/config) for every key.

## Directives

Directives are read from your source by the plugin. The CLI reads them when its input carries a source map. See [Directives](https://www.afterpack.dev/docs/directives).

## Edge cases

- **Fail-closed, with no override.** An `error`/`critical` [diagnostic](https://www.afterpack.dev/docs/diagnostics), an empty result, or a file the engine could not obfuscate [fails the build](https://www.afterpack.dev/docs/diagnostics#exit-codes).
- **Server output is just JavaScript.** AfterPack obfuscates whatever `.js` it finds in the directory you point it at.

## Next

- [Frameworks](https://www.afterpack.dev/docs/frameworks): the full matrix.
- [Vite](https://www.afterpack.dev/docs/frameworks/vite): the plugin this page recommends.
- [CLI reference](https://www.afterpack.dev/docs/cli#flags): the full flag list.
- [Configuration](https://www.afterpack.dev/docs/config): every option, and which surface can set it.
- [Presets](https://www.afterpack.dev/docs/presets): the ladder `preset` resolves against.
- [Builds & CI](https://www.afterpack.dev/docs/builds): seeds, dev-vs-prod, promoting the same bytes.
- [Protection Map](https://www.afterpack.dev/docs/protection-map): reading the report.
