Skip to main content
Today marks a first for Anvil2: a set of components has graduated from beta to stable. SelectField, MultiSelectField, SelectMenu, and MultiSelectMenu are now available from the @servicetitan/anvil2 stable package export. At the same time, Combobox is formally deprecated.
If you’re importing any of these components from @servicetitan/anvil2/beta, update your imports now. The beta export remains available until Anvil2 4.0 but will log a deprecation warning in development.

What’s changing

Four select components are now stable

The following components are exported from @servicetitan/anvil2:
ComponentUse when
SelectFieldSingle-select with a search input in a form field layout
SelectFieldSyncSame as SelectField, with sync option loading
MultiSelectFieldMulti-select with chips in a form field layout
MultiSelectFieldSyncSame as MultiSelectField, with sync option loading
SelectMenuSingle-select without a form field wrapper
SelectMenuSyncSame as SelectMenu, with sync option loading
MultiSelectMenuMulti-select without a form field wrapper
MultiSelectMenuSyncSame as MultiSelectMenu, with sync option loading

Combobox is deprecated

Combobox is deprecated and will be removed in Anvil2 5.0. It will continue to work in the meantime, but the console will log a one-time warning in development to remind you to migrate. The select field components are a direct replacement. They cover everything Combobox handles, plus lazy loading, grouping, and multi-select.

Why this is a milestone

The beta lifecycle exists so we can ship components into production before their APIs are locked down. That gives you access to new capabilities early and gives us room to refine based on real usage. The flip side is that using beta components comes with the expectation of occasional migration work. Graduating to stable is how that lifecycle is supposed to end. It’s a signal that the component has been through enough real-world usage that we’re confident in the API, and we’re committing to backward compatibility going forward. The select components are the first components to complete that journey in Anvil2. There are more components in beta today, and they’ll each follow the same path as they stabilize.

How to migrate

Update import paths

For most consumers, the migration is a find-and-replace:
// Before
import { SelectField, SelectFieldSync } from "@servicetitan/anvil2/beta";
import { MultiSelectField } from "@servicetitan/anvil2/beta";

// After
import { SelectField, SelectFieldSync } from "@servicetitan/anvil2";
import { MultiSelectField } from "@servicetitan/anvil2";
No prop changes are required. The components are identical at the API level — only the import path changes.

Migrate from Combobox to SelectField

The Combobox API is structured quite differently from the select components. Combobox uses a render-prop pattern with several required sub-components (Combobox.SearchField, Combobox.Content, Combobox.List, Combobox.Item) and accepts generic typed items with separate itemToString and itemToKey converters. The select components have a flat, declarative API — you pass an options array and they handle rendering internally.
// Before (Combobox)
import { Combobox } from "@servicetitan/anvil2";

<Combobox
  items={items}
  itemToString={(item) => (item ? item.name : "")}
  itemToKey={(item) => (item ? item.id : null)}
  selectedItem={selectedItem}
  onChange={setSelectedItem}
  filterOptions={{ keys: ["name"] }}
>
  <Combobox.SearchField label="Label" />
  <Combobox.Content>
    {({ items }) => (
      <Combobox.List>
        {items.map((item, i) => (
          <Combobox.Item key={item.id} item={item} index={i}>
            {item.name}
          </Combobox.Item>
        ))}
      </Combobox.List>
    )}
  </Combobox.Content>
</Combobox>

// After (SelectFieldSync)
import { SelectFieldSync } from "@servicetitan/anvil2";

<SelectFieldSync
  label="Label"
  options={items.map((item) => ({ value: item.id, label: item.name }))}
  value={selectedItem?.id ?? null}
  onChange={(value) => setSelectedItem(items.find((i) => i.id === value) ?? null)}
/>
Because the migration involves more than swapping an import, a dedicated migration guide and codemod will be published before Anvil2 5.0. We’ll announce that in #ask-designsystem when it’s ready. In the meantime, the SelectField code docs and MultiSelectField code docs are the best reference for the target API.
For the full migration details for each promoted component, see the individual beta-changes pages:

Breaking change timeline

ChangeVersion
Beta export deprecated (warning logged)Now
Beta export removedAnvil2 4.0
Combobox deprecated (warning logged)Now
Combobox removedAnvil2 5.0
The 4.0 release is planned for early August. When future releases are planned, we’ll communicate timelines well in advance through #ask-designsystem.

Questions?

Reach out in #ask-designsystem or check the component docs for full API details.
Last modified on June 23, 2026