Skip to main content
Resources to help migrate from Anvil to Anvil2. This guide is for ServiceTitan product squads attempting to migrate from Anvil (referenced as Anvil1 going forward to avoid confusion) to Anvil2. More specifically,
  • for engineers, this is the migration guide for @servicetitan/design-system to @servicetitan/anvil2,
  • for designers, this guide is for the switch from the Anvil Web to Anvil2 Figma library, and
  • for product managers, this guide covers how to plan the swap and when a user-facing change needs a notice.
This document will cover the high-level changes to the design system, and the breaking changes to component APIs and implementation standards. Follow the links to specific component documentation for a deeper understanding.

Migrating to Anvil2

As of the initial 1.0.0 release, there are a few components that are not included that we plan to make available soon. Check out the component mapping guidelines below for more information. While we work on some of the unreleased components, there is a good chance that upgrading will require using both Anvil1 and Anvil2 for a period of time. Reach out to the Anvil team if you need any assistance or have questions!

React Requirement

To use Anvil2, the consuming project needs to use React 18 or React 19. Read more about upgrading to React 18 in the Front-End Platform blog.

Getting Started Documentation

See our Getting Started page for more details about installing Anvil2 and the basic requirements for using it in an application.

Swapping Libraries

  • Once the Anvil2 Web package is installed, components can be imported as follows.

CSS Updates

CSS Utilities

CSS Utility classes have been trimmed down considerably in Anvil2. Many of the classes were rarely (if ever) used, or can be replaced with components like Flex and Grid. At a high level, here is what has changed:
  • Any utility classes from Anvil1 for flex, grid, display, position, alignment, height, width, z-indexing, border radius, line height, or white space have been removed.
  • Spacing classes (margin and padding), now use inline and block properties rather than left/right/top/bottom. This enables easier internationalization using CSS but does require changing the class names. For example, .m-l-1 is now .m-inline-start-1. Learn more in the mdn docs.
  • Spacing values (-1, -2, etc.) now use rem units for better accessibility.
  • Most classes use CSS variables, which are provided by the ThemeProvider or AnvilProvider. A fallback value is provided for use outside of a provider.
  • Utility classes can be imported all at once, or by utility type:
See the CSS Utilities reference for the full class list, naming conventions, and setup instructions.
There are currently two versions of the CSS Utilities:
  • utils.css - includes all utility classes
  • a2-utils.css - includes all utility classes prefixed with a2-
In the future, we will deprecate the classes without the a2- prefix, so we recommend using the a2- versions going forward.

Component CSS

One important change in Anvil2 is how component CSS is imported and bundled (or, not bundled in this case). In Anvil, a large CSS import that included bundled styles from all components was required. In Anvil2, each component imports its own CSS. Ideally, this means that your application will only bundle the CSS it needs for the Anvil2 components that are included in the app. This also means that consuming applications will only need to directly import CSS from Anvil2 if they are using the CSS Utilities.

CSS Modules

Anvil2 also uses CSS Modules to prevent style conflicts and accidental overrides. In general, overriding styles should be avoided to maintain consistency, but in some cases it may still be necessary. To add custom styling to an Anvil2 component, use either a className or style object.

Component Updates

We reviewed all of the Anvil1 components and made some significant changes for Anvil2. We trimmed down the library, renamed or repurposed some components, and added a few new ones. The information and links below should help when navigating these changes.

Component Mapping

Some components from Anvil1 have been renamed or replaced in Anvil2. The list below includes changes in component names and notes about significant changes from Anvil1 to Anvil2. Figma component names follow this mapping. Teams also use the Anvil1 to Anvil2 mapping document when they plan the rename outside this guide. The following table includes components that have been replaced in Anvil2 and will require some refactoring in consuming projects. Anvil1 components missing from this list have either been removed (see the “Components Omitted in Anvil2” section below) or are still available in Anvil2. * Not available currently, but planned for a future release. See the Roadmap for more information.

Date Picker values

Anvil1 Date Picker and Date Range Picker components used JavaScript Date objects for value and onChange. Anvil2 date fields use ISO 8601 date strings instead. Convert existing Date values before passing them to Anvil2 date fields:
See Date Values for conversion patterns with Luxon, Moment, and JavaScript Date objects.

Roadmap

View the Anvil2 roadmap and upcoming features.

Suggest an idea

Have an idea for a component, pattern, or documentation? Fill out the Feature Request Form in Slack.

Layout in Anvil2

Adjusting layouts has changed in Anvil2. The Flex and Grid components can be used to build layouts using Flexbox and CSS grid properties. These two components can be used in combination with each other along with component-specific layout props, which allows for more flexibility than the Stack and Layout components in the original Anvil1 library.

Component Layout Props

On the component-level, most Anvil2 components accept Layout props, which includes several Flex and Grid CSS shortcuts, as well as responsive breakpoint props. Components that do not use Layout props:
  • Dialog
  • Drawer
  • Label
  • Menu
  • Popover
  • Toast
  • Tooltip

Flex

Create layouts using CSS Flexbox.

Grid

Create layouts using CSS Grid.

Layout props

Apply CSS Flexbox and Grid properties to components.

Other Notable Breaking Changes

Code

The following components may require some refactoring to use in Anvil2.
  • Announcement
    • The actionName and onActionClick props have been removed. Instead, add action buttons as children of the Announcement.
  • Badge/Tag → Chip
    • Separate component for Badge rather than variation of the Tag.
    • Use label instead of children.
  • Banner → Alert
    • Replace action button props with action buttons in the children of the Alert.
  • Pickers → Fields
    • Coming soon! All picker components (Date Picker, File Picker, etc.) will be replaced with field components.
  • Modal → Dialog
    • The title and footer props have been replaced with the Dialog.Header and Dialog.Footer components, which can be passed as children of the Dialog.
    • Dialog should not be conditionally rendered - use the open prop to show or hide. Read more about this here.
  • Drawer
    • Drawer should not be conditionally rendered - use the open prop to show or hide. Read more about this here.
  • Option List → List View or Listbox
    • List Views include checkboxes.
    • Listboxes are generally used within confined spaces, such as a dropdown or side bar.
    • Both components use children rather than the options prop to render items.
  • Progress Tracker → Stepper
    • The Stepper.Step sub-components should be children of a Stepper.List.
    • The Stepper.List, Stepper.Panel, Stepper.NextButton, Stepper.PrevButton, and Stepper.FinalPanel sub-components can be used as children of the Stepper.
  • Select → Select Field for single selection or Multi Select Field for multiple selection
    • SelectFieldSync takes value as the option or null and onSelectedOptionChange. MultiSelectFieldSync takes value as an array and onSelectedOptionsChange. Options are { id, label }.
    • Both search options within an overlay. Pass options to SelectFieldSync or MultiSelectFieldSync, or loadOptions to SelectField or MultiSelectField for options loaded from a server.
    • Refer to the Select Field and Multi Select Field docs for implementation details.
  • Table → Data Table (beta)
    • Data Table has been completely rewritten in Anvil2. Refer to the Data Table docs for more information.
  • Tab
    • The Anvil2 Tab uses a few sub-components to construct the buttons and panels, and is an uncontrolled component.
    • In Anvil2, the controls and id props of the Tab.Panel and Tab.Button are used to determine which panel is opened by which button.
  • Toast
    • The Anvil2 Toast implementation has undergone a complete overhaul. Rather than using state to control when a toast message is displayed, a set of toast methods are available to display, hide, and update toast messages can be used. See the Toast docs to learn how.
    • The Anvil team and the Front-End Platform team established a holistic solution to avoid issues with using both Anvil1 and Anvil2.

Design

  • The Figma library now uses Figma variables to manage styles. This allows for easier text styling usage in addition to native dark mode support.
  • Usage of instance swapping in several components, such as Dialog and Drawer, allowing for components to make better use of autolayouts.
  • Improved support for suggested content in a component, such as options provided in the Combobox Popover and multiple Tabs in a single instance.
  • More consistent application of visual states (e.g., Hover, Active, Focus).
Recreate main screens with Anvil2 components so the layout stays on the Anvil2 grid. If you have to detach a component to get the result you need, tell the Anvil team.

Component Status in Figma

Anvil1 components in Figma use these statuses:
  • Deprecated. An Anvil2 replacement exists. Do not use the Anvil1 component.
  • Removed. The component is not used in Anvil1 or Anvil2.
  • Considering. The Anvil team has not decided whether to move it to Anvil2.
  • Coming soon. The component is on the roadmap and is not built yet.
  • Same name, different behavior. The Anvil2 component keeps the Anvil1 name and behaves differently. Read that component’s page.

Components Omitted in Anvil2

The following Anvil1 components are no longer available in Anvil2:
  • Backdrop
  • Collapsible
  • Mask
  • More details
  • Select
  • Sidebar (integrated into Page)
  • Snackbar

Components not currently available

The following components are not currently available in Anvil2, but are under consideration or planned to be released later. The following list is updated quarterly:
  • Color Picker **
  • File Picker **
  • Form *
  • Inline Edit * Q1 FY27
  • Status Light *
* Under consideration for Anvil2, depending on priority and feedback. ** Work is already planned as noted.

Migrate gradually as we release more components

As we work on these components, we expect that consuming projects will need to continue to use Anvil1 components that are not yet released in Anvil2. There should be no issues using Anvil1 alongside Anvil2 until the full catalog of components are available, but please reach out to the Anvil team on Slack if you need assistance.
Any net-new designs at ServiceTitan should use Anvil2 going forward. Anvil1 components can be used sparingly when necessary. If an Anvil1 component must be used within a net-new design, plan for a swap via UX Debt.Refer to the Anvil1 docs when using these components. We will keep this migration guide updated as more components become available in Anvil2!

For product managers

Plan the swap as BAU

Swapping Anvil1 components for Anvil2 components is UX debt and can be planned as business as usual. Read how to address your product needs for the planning steps, and ask the Anvil team when the swap needs help.

Decide when users need a change notice

A straight component swap often changes the interaction and little else. Some swaps also simplify the UI to meet accessibility requirements or to shorten the task. Review a larger change with your designer. Decide whether the flow needs a Pendo message or a Design Change Management pattern. The squad decides how much the change affects the user.
Last modified on November 4, 2026