Migrating from Anvil2 1.x to 2.0
Anvil2 2.0 is a major release that removes all previously deprecated APIs, standardizes component composition, and updates several required props. Because deprecated APIs have been fully removed, upgrading from v1.x will surface build-time errors that must be resolved before your application can compile.
This guide walks through the required changes and common migration patterns.
- Deprecated components and props have been removed and will now throw build errors
- Several internal sub-exports that were accidentally surfaced are no longer exported; use the existing compound/component namespace API instead
- Several previously optional props are now required
- Overlay components no longer have a fallback for browsers without HTML Popover support.
- Some Icon filenames have been renamed for consistency
Component Behavior Changes
Chip
When using size="small", Chip now allows only one of the following props:
// ❌ Invalid
<Chip size="small" onChange={handleChange} onClose={handleClose} />
// ✅ Valid
<Chip size="small" onChange={handleChange} />
Overlay Components
The following components using the HTML Popover API no longer have a fallback:
Tooltip
Popover
Menu
Combobox
No API changes are required, but this change requires that consumers of Anvil2 use a browser that is compatible with the HTML Popover API.
Removed Exports → Compound Component APIs
Several components previously exposed internal sub-exports at the package surface. Those internal exports are now removed from the public surface. Use the existing compound / namespaced APIs instead.
Dialog
// ❌ Removed exports
import {
DialogContent,
DialogHeader,
DialogFooter,
DialogCancelButton,
} from "@servicetitan/anvil2";
// ✅ Use the compound API
<Dialog>
<Dialog.Header />
<Dialog.Content />
<Dialog.Footer />
<Dialog.CancelButton />
</Dialog>
SideNav
// ❌ Removed exports
import { SideNavLink, SideNavGroup } from "@servicetitan/anvil2";
// ✅ Use the compound API
<SideNav>
<SideNav.Group>
<SideNav.Link />
</SideNav.Group>
</SideNav>
Other Components Using the Same Pattern
| Component | Removed Export(s) | Replacement API |
|---|
| Breadcrumbs | BreadcrumbsElement | Breadcrumbs |
| Checkbox | CheckboxGroup | Checkbox.Group |
| Details | DetailsSummary, DetailsContent | Details.Summary, .Content |
| Popover | PopoverTrigger, PopoverContent, PopoverClose, PopoverButton | Popover.Trigger, .Content, .Close, .Button |
| Radio | RadioGroup | Radio.Group |
| SelectCard | SelectCardElement, SelectCardGroup | SelectCard, SelectCard.Group |
| Toolbar | ToolbarElement, ToolbarButton, ToolbarSelect | Toolbar, Toolbar.Button, .Select |
Removed Components
DateField
The deprecated DateField component has been removed.
// ✅ Replace with one of:
<DateFieldSingle />
<DateFieldRange />
Removed / Replaced Props
All deprecated props have been removed in 2.0 and will now cause build errors.
Dialog
- Removed:
- Use instead:
onOpenAnimationStart
onOpenAnimationComplete
onClose
Popover
- Removed:
onOpenChange
onOutsidePress
disableFocusLock
root
- Replacements:
// ❌ Removed
<Popover onOutsidePress={handleOutside} disableFocusLock root />
// ✅ Updated
<Popover onClickOutside={handleOutside} modal />
Popover.Trigger
data-state has been replaced with aria-expanded
Drawer
- Removed:
onOpen
- Use:
onOpenAnimationStart
onOpenAnimationComplete
Calendar
// ❌ Removed
unavailableDates
// ✅ New API
unavailable={{ dates: [...] }}
Flex
flexShrink has been replaced by shrink.
// ❌
<Flex flexShrink="1" />
// ✅
<Flex shrink="1" />
Textarea
errorAriaLive no longer accepts a boolean
// ❌
errorAriaLive={true}
// ✅
errorAriaLive="assertive" // "polite" | "off"
Toaster
Toast duration must now be set on individual toasts.
Field-Level openMoreInfo
Removed from the following components:
FieldLabel
Combobox.Trigger
SelectTrigger
Textarea
// ❌
openMoreInfo
// ✅
moreInfoOpen
Link
// ❌
<Link quiet />
// ✅
<Link ghost />
Newly Required Props
The following props are now required and must be provided to avoid build errors:
| Component | Required Prop |
|---|
RadioGroup | legend |
Toolbar.Button | onClick |
Icon Renames
Several icons were renamed for consistency. Update any imports or asset references accordingly:
| Old Name | New Name |
|---|
gnav_dial_pad_filled.svg | gnav_dial_pad_active.svg |
gnav_dial_pad_inactive_outline | gnav_dial_pad_disabled.svg |
gnav_dial_pad_outline.svg | gnav_dial_pad_inactive.svg |
gnav_home_filled.svg | gnav_home_active.svg |
gnav_home_outline.svg | gnav_home_inactive.svg |
gnav_legacy_search_filled.svg | gnav_legacy_search_active.svg |
gnav_legacy_search_outline.svg | gnav_legacy_search_inactive.svg |
Optional: Anvil2 v2 Migration Claude Skill
To help teams prepare for the Anvil2 v2 migration, an optional Claude skill is available that scans the codebase for deprecated Anvil2 patterns and applies safe, mechanical fixes where possible.
Thanks to Kiryl Chetyrbak for creating and sharing this Claude skill.
Script location:
https://github.com/servicetitan/ai-codegen-tools/blob/master/plugins/skills/preparing-anvil2-migration/SKILL.md
What the script does
The script performs a structured migration pass with the following workflow:
- Scans the codebase for known Anvil2 v2 deprecations
- Applies automatic fixes for clear, unambiguous replacements
- Flags items that require manual decisions or review, including file locations
- Produces a summary of changes made and remaining action items
Types of changes it handles
The script covers a broad set of Anvil2 v2 migration rules, including:
- Renamed exports and components
- e.g.
BreadcrumbsElement → Breadcrumbs
- Pascal-case subcomponents migrated to dot notation
- e.g.
DialogContent → Dialog.Content
- Icon naming changes
- Prop renames and removals
- e.g.
quiet → ghost, removed Menu.open
- Event handler changes
- e.g.
onOpen → onOpenAnimationStart / End
- Component replacements
- e.g.
DateField → DateFieldSingle / DateFieldRange
- Import path updates
- e.g.
TooltipContext moved to @servicetitan/anvil2/base
- Context-based fixes
- Infers missing
RadioGroup legends
- Chooses
DateFieldSingle vs DateFieldRange based on usage
Some migrations cannot be resolved automatically. In these cases, the script will stop and ask for guidance, for example:
Chip size="small" with both onClick and onClose
Toolbar.Button without an onClick handler
What this script does not do
- It does not guarantee full Anvil2 v2 compatibility
- It does not replace manual review or testing
- It should not be treated as a one-click migration
When to use it
We recommend running this script early in the migration process to:
- Reduce manual discovery of deprecated patterns
- Apply consistent, mechanical fixes automatically
- Surface migration decisions before deeper refactors begin
This script is a convenience tool, not a required or officially supported migration step. Teams remain responsible for validating behavior, accessibility, and visual correctness after migration.