# Migrate from Vercel

This page moves the configuration of a Vercel project to Bastide: the `vercel.json`, the build settings and the environment variables. The code is deployed like any repository (see [Create a project](project.md) then [Deploy](deploy.md)); the importer touches neither the repository nor the Vercel project.

## Before you start

- A Bastide project already created (`project_create_with_backend`), where you hold the maintainer role (`maintainer`): that is the rank the acknowledgement and the variables import require.
- The content of your `vercel.json`.
- For the variables only: a Vercel API token limited to the project. A token scoped to a whole account is refused. The token is used read-only, is never stored, and is erased at the end of the call.

## 1. Import the configuration

The `vercel_import.create` operation reads the `vercel.json` (redirects, rewrites, headers, `cleanUrls`, `trailingSlash`, crons, functions) and the build settings you provide. It writes nothing into the project: it returns the `glowsoft.json` to version and a three-category report, kept, adapted, no equivalent.

```
glowsoft vercel_import create --project-id <prj_…> --vercel-json "$(cat vercel.json)"
```

The `vercel_import_create` MCP tool takes the same arguments. Replayed with the same idempotency key (`--idempotency-key`), the operation returns the first response.

The response carries `importId` (`ivc_…`), `counts` (`kept`, `adapted`, `noEquivalent`, `pendingAcknowledgement`), `items` (one line per element, with its sentence and the action to take) and `settings.rootDirectory`, which is not written into the repository: apply it with `project.settings.write`. Version the returned `glowsoft.json` at the root of the repository.

## 2. Import the variables

Variables are never written into a versioned file. A person imports them with the source token:

```
glowsoft vercel_import variables create --project-id <prj_…> --import-id <ivc_…> --token <vercel-token> --vercel-project-id <name-or-id>
```

Targets map as follows: `production` goes to production, `preview` to staging, a branch's `preview` to the environment that follows that branch. No value appears in the response or in the report. If the source goes silent or refuses, `interrupted` says what was written before the rest. Every call to the source is logged (`calls`). This operation has no MCP tool: a third-party account token does not pass through an agent. Run it with the command line or the HTTP API, under a personal token.

What you write by hand goes through `env.write.*`, and is undone with `env.delete.*`.

## 3. Acknowledge what has no equivalent

Each "no equivalent" line waits for the acknowledgement of an identified person; the migration is validated (`state: validated`) only afterwards.

```
glowsoft vercel_import accept --project-id <prj_…> --import-id <ivc_…>
```

Without `ranks`, every pending line is acknowledged. A service account token does not acknowledge, and the operation has no MCP tool: an agent does not validate in the person's place. Read the lines first: an acknowledgement is a declaration, it can be read back, no undo token is returned.

## 4. First deployment

Then deploy a branch with `deployment_create`, and read the build log: the build command is not carried over, the platform deduces it from the repository.

## Known incompatibilities

The importer's report names each one, with the action to take. These are the ones the importer can classify as "no equivalent" or "adapted".

`vercel.json` keys with no equivalent:

- `images`: the image transformer configuration has no declarative equivalent yet (TR-075). Keep the default sizes.
- `regions`: the execution region is not declared in the repository, it is the placement's. For a residency requirement, tell support.
- `functionFailoverRegions` and `passiveRegions`: no equivalent; a service keeps several instances in its region.
- `env` and `build`: never read or copied from a versioned file; use the variables import above.
- `routes`: legacy form, which Vercel forbids mixing with `redirects`, `rewrites` and `headers`; rewrite it into those three blocks, then rerun the import.
- `builds`: legacy form; the build is detected.
- `git`: no direct equivalent; declare in `glowsoft.json` the branches that deploy (`branches.patterns`).
- `github`: connect the repository through the platform's GitHub application.
- `public`: build logs stay private.
- `bunVersion`: the Bun version is a platform decision.
- `fluid`: a service is a container, the `fluid` execution mode has no equivalent.

Build settings the platform decides itself: `buildCommand`, `installCommand` and `outputDirectory` (the admitted commands form a closed catalogue, EX-BUILD-090), `ignoreCommand` (the skip is computed from the paths touched by the commit, the project's `includePaths`), `devCommand` (meaningless on the platform). If the detected plan does not build the project, declare a `build` script in `package.json`.

Adaptations: a redirect carrying both `permanent` and `statusCode` keeps the code, as Vercel applies it; a rewrite with `statusCode` loses that code (the response keeps the one the application gives it); a rewrite with `transforms` is entirely without equivalent, because dropping it would serve something other than what you wrote. A function's maximum duration becomes the service's request timeout, the longest of the patterns, with a floor of 30 s.

Gestures agents do not carry out, according to the parity report: `vercel_import.accept` (human validation, EX-MIG-020) and `vercel_import.variables.create` (identity) are closed to agents; `vercel_import.list`, which reads the imports back, is closed with no security reason (the MCP catalogue is full): read it in the console, `vercel_import.create` already returns the whole report.

The hundred real `vercel.json` files replayed on both platforms (EX-NET-460) are still to be done: the test files are fabricated from the published reference.

See also: [Migrate from Supabase](from-supabase.md), [Leave Bastide](leave.md).
