Abyss V2 is finally here! We've worked hard to make the transition from V1 as smooth as possible.
Troubleshooting
If you encounter any issues during the migration process, please post your questions, problems, or findings on GitHub Discussions. This will allow all teams to see, respond to, and benefit from shared solutions. If someone has already asked a similar question, consider adding your insights or upvoting the existing discussion rather than creating a duplicate. This helps keep the conversation organized and makes it easier for everyone to find relevant information.
Go to the V1 → V2 Migration Discussion
Getting started
The steps listed below will guide you through the migration process.
1. Update to the latest V1 version
Make sure your project is running on the most recent V1 release before starting any migration steps. This will help minimize potential issues during the migration process.
2. Update React
In Abyss V2, we have updated our peer dependencies for React and React DOM. Notably, React 16 and 17 are no longer supported in Abyss V2. You should ensure your application is running on React 18 or 19 before migrating to Abyss V2.
// V1- "react": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"- "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
// V2+ "react": "^18.0.0 || ^19.0.0"+ "react-dom": "^18.0.0 || ^19.0.0"3. Update component usage
It is strongly recommended to replacing your V1 components with their V2 counterparts before updating to Abyss V2. This way, when you move to V2, you will only need to update the import names (e.g., V2Button → Button) instead of making all the prop changes at the same time.
Deprecations
Below is a list of tools, hooks, and components that are no longer available in Abyss V2. To help identify these deprecated components in your codebase, we've created a codemod detection tool that scans your project for deprecated Abyss imports. See the Detect deprecated imports - Codemod section below for instructions on how to use this tool.
Web Deprecations
| V1 Abyss | Reason for Deprecation | Migration Path |
|---|---|---|
Name: ActionNavImport Path:@uhg-abyss/web/ui/ActionNav | Doesn't align with the Abyss Design system |
|
Name: CheckboxTreeImport Path:@uhg-abyss/web/ui/CheckboxTree | Doesn't align with the Abyss Design system |
|
Name: ContentEditorImport Path:@uhg-abyss/web/ui/ContentEditor | Doesn't align with the Abyss Design system |
|
Name: DragAndDropImport Path:@uhg-abyss/web/ui/DragAndDrop | Doesn't align with the Abyss Design system |
|
Name: DrawableCanvasImport Path:@uhg-abyss/web/ui/DrawableCanvas | Doesn't align with the Abyss Design system |
|
Name: DrawerMenuImport Path:@uhg-abyss/web/ui/DrawerMenu | Doesn't align with the Abyss Design system |
|
Name: FloatingSectionImport Path:@uhg-abyss/web/ui/FloatingSection | Doesn't align with the Abyss Design system |
|
Name: FocusableImport Path:@uhg-abyss/web/ui/Focusable | Doesn't align with the Abyss Design system | Teams can create their own focusable component using the styled tool. |
Name: FormBuilderImport Path:@uhg-abyss/web/ui/FormBuilder | Doesn't align with the Abyss Design system |
|
Name: FullscreenImport Path:@uhg-abyss/web/ui/Fullscreen | The | Use the |
Name: IconMaterialImport Path:@uhg-abyss/web/ui/IconMaterial | Google has deprecated the Material Icons library and instead moved to a font based icon library. | Move to |
Name: ItemizedInvoiceImport Path:@uhg-abyss/web/ui/ItemizedInvoice | Doesn't align with the Abyss Design system |
|
Name: LabelImport Path:@uhg-abyss/web/ui/Label | Doesn't align with the Abyss Design system | Move to |
Name: LagoonProviderImport Path:@uhg-abyss/web/ui/LagoonProvider | Lagoon is no longer included inside Abyss | Migrate to Lagoon SDK Lagoon components are now maintained independently of Abyss. Please refer to the Lagoon documentation and the Lagoon SDK implementation guide for migration assistance. |
Name: LoadingIconImport Path:@uhg-abyss/web/ui/LoadingIcon | Doesn't align with the Abyss Design system |
|
Name: MaelstromProviderImport Path:@uhg-abyss/web/ui/MaelstromProvider | Maelstrom has been moved out of Abyss | Use alternative authentication methods |
Name: MarkdownImport Path:@uhg-abyss/web/ui/Markdown | Doesn't align with the Abyss Design system |
|
Name: PrintProviderImport Path:@uhg-abyss/web/ui/PrintProvider | Printing is not a core feature of Abyss | Use a custom print solution or library |
Name: PropsContextProviderImport Path:@uhg-abyss/web/ui/PropsContextProvider | No reason for this to be maintained inside Abyss | Create own provider/context or move to other state management system |
Name: SearchResultsImport Path:@uhg-abyss/web/ui/SearchResults | Doesn't align with the Abyss Design system |
|
Name: ServiceSandboxImport Path:@uhg-abyss/web/ui/ServiceSandbox | Doesn't align with the Abyss Design system |
|
Name: StatusIndicatorImport Path:@uhg-abyss/web/ui/StatusIndicator | Doesn't align with the Abyss Design system |
|
Name: TemplateImport Path:@uhg-abyss/web/ui/Template | Doesn't align with the Abyss Design system |
|
Name: ToggleTabsImport Path:@uhg-abyss/web/ui/ToggleTabs | Doesn't align with the Abyss Design system | Move to |
Name: createStoreImport Path:@uhg-abyss/web/tools/createStore | Teams can maintain their own state management solution. | Pull in Zustand directly. |
Name: useLagoonImport Path:@uhg-abyss/web/hooks/useLagoon | Lagoon is no longer included inside Abyss | Migrate to Lagoon SDK Lagoon components are now maintained independently of Abyss. Please refer to the Lagoon documentation and the Lagoon SDK implementation guide for migration assistance. |
Name: useMaelstromImport Path:@uhg-abyss/web/hooks/useMaelstrom | Maelstrom has been moved out of Abyss | Use alternative authentication methods |
Name: usePrintImport Path:@uhg-abyss/web/hooks/usePrint | Printing is not a core feature of Abyss | Use a custom print solution or library |
Name: usePropsContextImport Path:@uhg-abyss/web/hooks/usePropsContext | No reason for this to be maintained inside Abyss | Create own provider/context or move to other state management system |
Name: LagoonFormImport Path:@uhg-abyss/utility/ui/LagoonForm | Lagoon is no longer included inside Abyss | Migrate to Lagoon SDK Lagoon components are now maintained independently of Abyss. Please refer to the Lagoon documentation and the Lagoon SDK implementation guide for migration assistance. |
Name: LagoonProviderImport Path:@uhg-abyss/utility/ui/LagoonProvider | Lagoon is no longer included inside Abyss | Migrate to Lagoon SDK Lagoon components are now maintained independently of Abyss. Please refer to the Lagoon documentation and the Lagoon SDK implementation guide for migration assistance. |
Name: MaelstromProviderImport Path:@uhg-abyss/utility/ui/MaelstromProvider | Maelstrom has been moved out of Abyss | Use alternative authentication methods |
Name: lagoonImport Path:@uhg-abyss/utility/tools/lagoon | Lagoon is no longer included inside Abyss | Migrate to Lagoon SDK Lagoon components are now maintained independently of Abyss. Please refer to the Lagoon documentation and the Lagoon SDK implementation guide for migration assistance. |
4. Update to the latest V2 version
Now that you've completed all preparation steps, you can update your project to use Abyss V2! Assuming that you have already replaced the deprecated V1 components with their recommended alternatives and switched all other components to their V2 counterparts, the migration to Abyss V2 should be straightforward.
Most of the remaining work should be import renaming rather than large-scale refactoring.
Remove the V2 prefix
We had released a number of V2 components in V1 with a V2 prefix to allow teams to start using them early and ease the migration process. Now that you are migrating to Abyss V2, you will need to remove the V2 prefix from these components in your imports. If you used an alias when importing, make sure to update that as well.
// Beforeimport { V2Button } from '@uhg-abyss/web/ui/Button';import { V2TextInput as TextInput } from '@uhg-abyss/web/ui/TextInput';
// Afterimport { Button } from '@uhg-abyss/web/ui/Button';import { TextInput } from '@uhg-abyss/web/ui/TextInput';Updating V1-prefixed components
Some existing components have been prefixed with V1 in Abyss V2 (e.g., DataGrid → V1DataGrid). We have done this because these components are not yet tokenized and will eventually receive a new design and functionality updates, but we want them to remain available in V2 for those teams who rely on them.
Once the new versions of these components are released, teams will need to remove the V1 prefix from their imports and update any props or patterns to match the new V2 design and API.
| V1 Component Name | V2 Legacy Equivalent |
|---|---|
DataGrid | V1DataGrid |
Charts | V1Charts |
SubNavigationMenu | V1SubNavigationMenu |
Table | V1Table |
Flyout | V1Flyout |
ToggleGroup | V1ToggleGroup |
Breaking changes
The V1 prefix approach allows teams to migrate to V2 with minimal immediate changes, keeping most existing functionality intact. However, due to dependency upgrades and API alignments, some breaking changes still exist. These changes are documented below so teams can address them during migration.
V1DataGrid
numericConfig.valueIsNumericString → numericConfig.isNumericString
Due to upgrading react-number-format from v4 to v5, the property name has changed.
// Before{ title: 'Percent Column', type: 'number', numericConfig: { suffix: '%', valueIsNumericString: false }}
// After{ title: 'Percent Column', type: 'number', numericConfig: { suffix: '%', isNumericString: false }}V1ToggleGroup
descriptorsDisplay has been removed
The descriptorsDisplay prop has been removed in V2. This prop was previously used to control the direction of the descriptors. All descriptors will now automatically stack vertically to improve readability and accessibility (same as "column" before).
// Before<V1ToggleGroup descriptorsDisplay="row" // or "column"/>
// After<V1ToggleGroup // Remove descriptorsDisplay prop/>UHG theme
The UHG theme has been removed in Abyss V2. To learn more about this change and how to migrate, please navigate to the UHG Theme documentation.
Theming
Some values in the overrides provided to the createTheme function have been removed to better align with brand design guidelines. If your project is using any of the following overrides, you will need to remove them.
deprecatedOptumIcons
The deprecatedOptumIcons override has been removed as the old Optum brand icons were not aligned with the Optum brand guidelines. Removing this override will ensure that your application uses the correct icons. No changes to your codebase are necessary beyond removing this override from your theme configuration.
Note that it was also possible to override a single BrandIcon with the useDeprecated prop. This prop is no longer supported in V2 and should be removed from all BrandIcon instances.
deprecatedFont
The deprecatedFont override has been removed from the Optum theme as the deprecated Optum Sans font is no longer a part of the Optum brand. Removing this override will ensure that your application uses the correct font, Enterprise Sans, as per brand guidelines.
The UHC theme still uses UHC Sans by default. You can use Enterprise Sans instead by setting the enterpriseFont flag to true in the theme configuration.
CSS styling with Emotion
In Abyss V2, we've replacing Stitches with Emotion for our CSS-in-JS solution. Both libraries have similar APIs, so most applications won't be significantly affected, but some breaking changes are possible depending on your current usage.
For migration steps and examples, see the Emotion migration guide.
Why are we migrating to Emotion?
- Stitches is no longer actively maintained and we want to use a library that is actively supported and has a strong community.
- Abyss Mobile has already migrated to Emotion and we want to maintain consistency across our products.
- Emotion provides a more flexible API.
- Emotion has better support for server-side rendering, which is important for our applications.
- Shadow DOM support
To read more, please refer to our ADR.
CSS class name prefix (styledPrefix removal)
The styledPrefix configuration option has been removed in Abyss V2. This setting was previously used to avoid CSS class name collisions when multiple applications or Parcels were embedded on the same page.
In V2, you can now control the CSS class name prefix directly in your application code using the StyleRootProvider with the cacheOptions prop. This provides better style isolation and is especially useful when combined with a shadow DOM.
Before (V1):
// .abyss/settings.json{ "styledPrefix": "my-app"}After (V2):
import { StyleRootProvider } from '@uhg-abyss/web/ui/ThemeProvider';import { ThemeProvider } from '@uhg-abyss/web/ui/ThemeProvider';import { createTheme } from '@uhg-abyss/web/tools/theme';
const theme = createTheme('uhc');
export const MyApp = () => ( <StyleRootProvider theme={theme} cacheOptions={{ key: 'my-app' }}> <ThemeProvider theme={theme}> <AppContent /> </ThemeProvider> </StyleRootProvider>);Routing
We have upgraded our routing system from v6 to v7 of react-router. This upgrade brings several enhancements and new features to improve the routing experience in your application. Check out their migration guide for more details.
Here are some key changes and improvements in the routing system:
- The
react-router-dompackage has been consolidated into the mainreact-routerpackage. - All routing functionality is available from
@uhg-abyss/web/tools/reactRouterTools. This package re-exports the completereact-routerpackage and is meant to prevent version conflicts across projects.
API
We have upgraded the @uhg-abyss/api package's express dependency from v4 to v5. For details on breaking changes and migration steps, see the Express v5 migration guide.
Parcels/workshop
Abyss is excited to announce that Parcels is officially out of beta!
Dependencies
We have upgraded @uhg-abyss/parcels package's storybook dependency from v8 to v10 in order to take advantage of the latest features and improvements. Due to Storybook v10 moving away completely from CommonJS to ESM, teams will need to update their story imports to include the resolution mode.
Before (V1):
import type { StoryObj } from '@storybook/react';After (V2):
import type { StoryObj } from '@storybook/react' with { "resolution-mode": "import" };Note: Abyss may explore moving from CommonJS to ESM in the future, but for now, this small import change ensures Storybook v10 compatibility with minimal disruption.
Shadow DOM
The shadowDOM flag in story configuration has been removed in Abyss V2. This flag was previously used to control shadow DOM behavior in Parcels, but due to limitations within Stitches, style isolation within the shadow DOM was not able to be achieved.
Before (V1):
export default { title: 'NoShadowDOMParcel', parcel: 'my-parcel', component: MyParcel, shadowDOM: false, // Flag to turn shadow DOM on or off};After (V2):
Style isolation within the Shadow DOM is now supported in V2. The shadow DOM is now controlled directly in your Parcel component code using StyleRootProvider with the useShadowDom prop. This provides more granular control and better integration with theming.
import { StyleRootProvider } from '@uhg-abyss/web/ui/ThemeProvider';import { ThemeProvider } from '@uhg-abyss/web/ui/ThemeProvider';import { createTheme } from '@uhg-abyss/web/tools/theme';
const theme = createTheme('uhc');
export const MyParcel = () => ( <StyleRootProvider useShadowDom // Enable Shadow DOM theme={theme} cacheOptions={{ key: 'my-parcel' }} > <ThemeProvider theme={theme}> <ParcelContent /> </ThemeProvider> </StyleRootProvider>);For more information on Shadow DOM configuration, see the Shadow DOM documentation.
Mutation observer
In Abyss V1, a disableMutationObserver flag was available in Parcel configuration. When not disabled, the MutationObserver would watch for property changes on a Parcel and trigger a full remount whenever those properties changed.
In Abyss V2, this behavior has been reversed.
The MutationObserver is now disabled by default in V2 to improve performance and preserve Parcel state. To opt into the previous remount-on-property-change behavior, a new flag, enableMutationObserver, has been introduced.
Why the change?
In V1, remounting on property change often caused state loss, UI flickering, and performance issues, especially in complex Parcels.
If your V1 Parcel relied on property changes to update its UI, you will need to explicitly enable the MutationObserver in V2 by setting "enableMutationObserver": true in your Parcel's settings.json.
For more details and examples, see the Updating Parcels documentation for more information.
Codemods and AI tools
We have created a few codemods to help with the migration process. These codemods aim to reduce the amount of manual work required to update your codebase.
AI-powered migration
To help with component migration, we offer an AI context package that works with tools like GitHub Copilot, ChatGPT, or other AI coding assistants. This context enables the AI to understand the V1 to V2 changes and provide accurate migration assistance.
Note: Please remember that AI is not perfect. Always review the generated code to ensure it performs migration steps accurately while meeting your requirements and adhering to best practices.
Using the AI migration info
Start by downloading the AI migration context ZIP folder, then extract it to your project root directory. The structure should look like this:
your-project-root/├── abyss-migration-ai-context/│ ├── ABYSS-MIGRATION-ASSISTANT.md| └── MigrationData.json├── package.json└── src/ └── ... (your project files)Add the context to your AI tool of choice (e.g., Copilot, ChatGPT, etc.) referencing the folder location. Then, you can prompt the AI tool with questions like:
- "Migrate this file from V1 to V2 of Abyss."
- "Migrate the
Buttoncomponent from V1 to V2 of Abyss."
Here is an example showcasing migrating a file from V1 to V2 of Abyss using the AI tool. Given this prompt:
"Migrate #file:HelloAbyss.tsx from V1 to V2 of Abyss."
Copilot was able to produce the following results:
Detect deprecated imports
To help with identifying deprecated components, we provide a script that scans your codebase for deprecated Abyss imports. This script will help you identify which components need to be replaced before migrating to v2.
Note: Abyss imports show deprecation warnings. This tool is used scan your codebase for all deprecated imports at once.
How to use the script
Start by downloading the script's ZIP folder, then extract it to your project root directory. The structure should look like this:
your-project-root/├── abyss-migration-tools/│ ├── scan-imports.sh│ ├── detect-deprecated-imports.js| └── deprecated-imports.json├── package.json└── src/ └── ... (your project files)Then, run the following commands to make the script executable and scan your codebase:
# Make the script executablechmod +x abyss-migration-tools/scan-imports.sh
# Run the script to scan your entire codebase./abyss-migration-tools/scan-imports.sh
# Or specify a specific directory to scan./abyss-migration-tools/scan-imports.sh src/componentsThe script will scan your codebase for deprecated Abyss imports and report any findings. For example, running the script might show output like this:
After identifying deprecated imports, refer to the deprecation table above for specific migration advice for each component or utility. For example, the table shows that createStore should be replaced with Zustand directly.