> ## Documentation Index
> Fetch the complete documentation index at: https://docs.forest.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Agent v1 to v2

> Complete guide to moving your setup from a legacy agent to the current generation.

This guide covers migrating from any v1 agent (`forest-express-sequelize`, `forest-express-mongoose`, `forest-rails`, `django-forestadmin` v1) to the current generation.

The migration unlocks workflows, the MCP server for AI agents, multi-datasource, decision traces, and everything Forest has shipped since the original admin-panel era. Most teams complete the migration in 1-2 days with zero downtime.

## What v2 changes

The new generation is a rebuilt agent with a cleaner, more composable customization API. The biggest changes you'll see during migration:

* **Multi-datasource is native.** A single agent can connect to multiple databases and APIs.
* **Customization happens via a fluent API on collections.** `agent.customizeCollection('users', users => users.addField(...))`.
* **Computed fields declare their dependencies explicitly.** `dependencies: ['firstName', 'lastName']`.
* **Relationships are first-class.** Many-to-one, one-to-many, many-to-many, and external relations replace most legacy "smart relationships".
* **Routes are no longer overridden directly.** Most v1 route overrides become hooks or computed fields.

## Before you start

<Steps>
  <Step title="Upgrade the legacy agent">
    Releases of `@forestadmin/forestadmin-client` before **1.36.2** cache a failed permission lookup for 15 minutes, so a slow response during one of the migration's restarts can lock users out of an environment.
  </Step>

  <Step title="Decide where the new agent will run">
    In-app or standalone: settle it before writing code. See [Deployment options](/get-started/connect/architectures/deployment-options).
  </Step>

  <Step title="Migrate into a new environment, not a new project">
    Layouts, segments, workspaces, roles and teams belong to the **project** and don't carry over to another one. Add an environment to your existing project (**Project Settings → Environments → Add**) and point it at the new agent.
  </Step>

  <Step title="Inventory your customizations">
    List every Smart Action, Smart Field, Smart Relationship, Smart Segment, and route override in your current project. Each step page below covers one of these surfaces.
  </Step>

  <Step title="Back up your project">
    Export your current Forest project layout. While the layout is preserved across the agent swap, having a baseline is good practice.
  </Step>

  <Step title="Plan parallel running">
    Both agents can run side by side during migration.
  </Step>
</Steps>

<Warning>
  **Running both agents in one process is not recommended**: every deploy of the new agent would also restart the legacy one you are relying on. If they share a host, they also need separate paths — see [Running two agents at once](/get-started/connect/architectures/deployment-options#running-two-agents-at-once).
</Warning>

## Migration steps

<Steps>
  <Step title="Install the new agent">
    Install the new packages alongside your existing ones, and run the new agent in its own process, on a different port.

    <Tabs>
      <Tab title="Node.js">
        ```bash theme={null}
        npm install @forestadmin/agent
        npm install @forestadmin/datasource-sql
        # or @forestadmin/datasource-mongo, @forestadmin/datasource-mongoose, etc.
        ```
      </Tab>

      <Tab title="Ruby">
        ```bash theme={null}
        # Gemfile
        gem 'forest_admin_agent'
        gem 'forest_admin_rails'
        gem 'forest_admin_datasource_toolkit'
        gem 'forest_admin_datasource_customizer'
        gem 'forest_admin_datasource_active_record'
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Migrate datasources">
    Re-declare your data sources using the new datasource API. See [Datasources](/guides/migration/from-v1/steps/datasources).
  </Step>

  <Step title="Match the old field names">
    Your layout refers to every field by name, so the new agent must expose the same names as the old one. A mismatch raises no error: the configuration on that field just disappears. Check this before migrating any customization — see [Datasources](/guides/migration/from-v1/steps/datasources#match-the-names-your-layout-already-uses).
  </Step>

  <Step title="Migrate Smart Actions">
    Convert each Smart Action to the new `addAction` API. See [Smart Actions](/guides/migration/from-v1/steps/smart-actions).
  </Step>

  <Step title="Migrate Smart Fields">
    Convert computed fields to `addField` with explicit dependencies. See [Smart Fields](/guides/migration/from-v1/steps/smart-fields).
  </Step>

  <Step title="Migrate Smart Relationships">
    Convert legacy smart relationships to native relations or external relations. See [Smart Relationships](/guides/migration/from-v1/steps/smart-relationships).
  </Step>

  <Step title="Migrate Smart Segments">
    Update segments to use condition trees instead of ORM-specific queries. See [Smart Segments](/guides/migration/from-v1/steps/smart-segments).
  </Step>

  <Step title="Rehearse against your real layout">
    A branch starts from production's layout, so you can test the new agent against it without touching production:

    ```bash theme={null}
    forest branch migration-rehearsal --origin production
    ```

    Naming mistakes show up here as missing columns or broken actions. This is usually enough.
  </Step>

  <Step title="Populate a shared test environment (optional)" id="populate-a-shared-test-environment">
    Only if your team needs a shared pre-production environment. A new environment in the same project inherits production's layout, but not its role permissions. Production runs the legacy agent and `node-test` the new one, so their schemas differ and [copying permissions across environments](/get-started/control/roles-permissions#copy-permissions-across-environments) refuses them. Move the permissions through a file instead, once the new agent has started on `node-test`:

    1. Back up the target, so you can re-apply it to undo: `forest roles:export --env node-test --output node-test-backup.csv`
    2. Export production: `forest roles:export --env production --output roles.csv`
    3. Rename the columns to the new agent's names. The file has one column per collection permission and Smart Action grant, headed `collection:permission` or `collection:action:grant`. If you [kept the legacy names](/guides/migration/from-v1/steps/datasources#match-the-names-your-layout-already-uses), there's nothing to rename. Drop the columns of collections the new agent doesn't expose: a column naming a collection the environment doesn't have fails that role's update.
    4. Apply it: `forest roles:apply --env node-test roles.csv`. It lists the changes and asks before applying them.

    Smart Action conditions aren't carried over. Set them again on the new environment.
  </Step>

  <Step title="Test side by side">
    Run both agents simultaneously. Point the test environment at the new agent and verify behavior matches the legacy one, especially actions, computed fields, and segments.
  </Step>

  <Step title="Switch your environment URL">
    Once you're confident, point your production environment's URL at the new agent. The UI configuration is preserved.
  </Step>

  <Step title="Keep the rollback available">
    To roll back, point the URL back at the legacy agent. Keep it running until you're sure you won't need to.
  </Step>

  <Step title="Remove legacy packages">
    Once production has been stable on the new agent for a few days, remove the legacy packages and clean up the old code.
  </Step>
</Steps>

## What's preserved

Your Forest UI configuration is **not** affected by the agent migration:

* Layouts, segments, dashboards, charts
* Roles, permissions, scopes, teams
* Workspaces, workflows, inboxes
* Approval workflow configurations
* Smart Action visibility settings

These all live in Forest's UI configuration and continue to work as long as the new agent exposes the same collection and field names.

## What needs updating

| Surface | Where it changes | Step page |
| - | - | - |
| Datasource configuration | Code | [Datasources](/guides/migration/from-v1/steps/datasources) |
| Smart Actions | Code | [Smart Actions](/guides/migration/from-v1/steps/smart-actions) |
| Smart Fields | Code | [Smart Fields](/guides/migration/from-v1/steps/smart-fields) |
| Smart Relationships | Code | [Smart Relationships](/guides/migration/from-v1/steps/smart-relationships) |
| Smart Segments | Code | [Smart Segments](/guides/migration/from-v1/steps/smart-segments) |
| Route overrides | Reimplemented as hooks | See [Hooks](/product/process/advanced-concepts/hooks/overview) |
| ORM model callbacks | Some stop firing, depending on the datasource | See [Common issues](#common-issues) |
| Where the agent runs | Decided before you start | [Deployment options](/get-started/connect/architectures/deployment-options) |
| Environment variables | `FOREST_ENV_SECRET` and `FOREST_AUTH_SECRET` are reused | No change |
| Database | No change | No change |

## Common issues

<AccordionGroup>
  <Accordion title="Field names changed between v1 and v2">
    Restore the old names with `rename` (collections) and `renameField` (fields) rather than editing the layout — see [Datasources](/guides/migration/from-v1/steps/datasources#match-the-names-your-layout-already-uses).
  </Accordion>

  <Accordion title="My ORM has no datasource (TypeORM, Prisma, Drizzle...)">
    Sequelize, Mongoose, ActiveRecord and Mongoid have matching datasources. Other Node.js ORMs connect through [`datasource-sql`](/get-started/connect/data-sources/sql), or [`datasource-mongo`](/get-started/connect/data-sources/mongodb) for MongoDB. Both read the database directly. That works, but your model callbacks won't fire, and the agent introspects the whole schema at every boot unless you [cache it](/get-started/connect/data-sources/sql#caching-introspection).
  </Accordion>

  <Accordion title="A model callback stopped firing">
    Whether a callback fires depends on the datasource:

    * **`datasource-sequelize`**: per-record hooks such as `beforeCreate` don't run ([details](/get-started/connect/data-sources/sequelize#which-hooks-run-on-a-write-from-forest)).
    * **`datasource-mongoose`**: `save` middleware doesn't run.
    * **ActiveRecord**: all callbacks run as before.
    * **Mongoid**: callbacks run on create and single-record edits, not on multi-record edits or deletes.
    * **`datasource-sql`**: none of your callbacks run.

    If one that no longer fires must run on Forest edits, move it into an [agent hook](/product/process/advanced-concepts/hooks/overview). Don't reimplement one that still fires, or it runs twice.
  </Accordion>

  <Accordion title="Can I reuse my v1 .forestadmin-schema.json?">
    Not as the new agent's schema: the two generations write different formats. Keep it to diff against while you check names.
  </Accordion>

  <Accordion title="A Smart Action's form behaves differently">
    The Smart Action form API is more structured in v2. Fields are declared explicitly. See [Smart Actions](/guides/migration/from-v1/steps/smart-actions) for the new form syntax.
  </Accordion>

  <Accordion title="A computed field is slow">
    The new agent supports batched computed fields: `getValues` receives an array of records. If you naively port a v1 `get` function inside a `.map(async ...)`, you'll keep the same N+1 problem. Aggregate the underlying query.
  </Accordion>

  <Accordion title="A relationship doesn't appear in the UI">
    The new relationship API requires you to declare both sides. If you only declared one direction, the UI may not surface it. See [Smart Relationships](/guides/migration/from-v1/steps/smart-relationships).
  </Accordion>
</AccordionGroup>

## Get help

<CardGroup cols={3}>
  <Card title="Step pages" href="/guides/migration/from-v1/steps/datasources">
    Per-feature migration instructions with side-by-side examples.
  </Card>

  <Card title="Community" href="https://community.forestadmin.com">
    Migration questions and patterns from other teams.
  </Card>

  <Card title="Support" href="mailto:support@forestadmin.com">
    Direct help from the Forest team.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.