Registry
Explore community-led codemods to migrate, optimize, and transform your codebase.
Ready to contribute?
Build your own codemod and share it with the community.
Explore community-led codemods to migrate, optimize, and transform your codebase.
Build your own codemod and share it with the community.
Explore community-led codemods to migrate, optimize, and transform your codebase.
Transform React class components to modern function components
## Example This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it. ### Before ```ts import React from 'react'; import PropTypes from 'prop-types'; import { makeStyles, useTheme } from '@material-ui/styles'; import classNames from 'classnames'; import Button from '../../../../components/controls/Button'; import ButtonLoader from '../../../../components/loaders/ButtonLoader'; import makeStateElementName from '../../../../theme-editor/utils/makeStateElementName'; const useStyles = makeStyles((theme) => ({ stakeButton: ({ editorId }) => ({ width: '100%', height: 40, fontWeight: 600, ...theme[editorId], }), stakeButtonDisabled: ({ editorId }) => ({ ...theme[`${makeStateElementName(editorId, 'disabled')}`], }), '@media (hover: hover)': { stakeButtonDisabled: ({ editorId }) => ({ '&:hover': { ...theme[`${makeStateElementName(editorId, 'disabled')}`], }, }), }, loaderContainer: { width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', }, })); const StakeInputButton = ({ onClick, isDisabled, children, className, isLoading, dataEditorId, }) => { const classes = useStyles({ editorId: dataEditorId }); const theme = useTheme(); return ( < Button elementClasses = { { default: classNames(classes.stakeButton, className), disabled: classes.stakeButtonDisabled, } } disabled = { isDisabled } onClick = { onClick } style = { { padding: 0, } } dataEditorId = { dataEditorId } > { isLoading ? ( < div className = { classes.loaderContainer } > < ButtonLoader color = { theme.brandButton.color } /> < /div> ) : ( children ) } < /Button> ); }; StakeInputButton.propTypes = { dataEditorId: PropTypes.string, }; StakeInputButton.defaultProps = { dataEditorId: 'betslipPlaceBetButton', }; export default StakeInputButton; ``` ### After ```ts import React from 'react'; import PropTypes from 'prop-types'; import { makeStyles, useTheme } from '@material-ui/styles'; import classNames from 'classnames'; import Button from '../../../../components/controls/Button'; import ButtonLoader from '../../../../components/loaders/ButtonLoader'; import makeStateElementName from '../../../../theme-editor/utils/makeStateElementName'; const useStyles = makeStyles((theme) => ({ stakeButton: ({ editorId }) => ({ width: '100%', height: 40, fontWeight: 600, ...theme[editorId], }), stakeButtonDisabled: ({ editorId }) => ({ ...theme[`${makeStateElementName(editorId, 'disabled')}`], }), '@media (hover: hover)': { stakeButtonDisabled: ({ editorId }) => ({ '&:hover': { ...theme[`${makeStateElementName(editorId, 'disabled')}`], }, }), }, loaderContainer: { width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', }, })); const StakeInputButton = ({ onClick, isDisabled, children, className, isLoading, dataEditorId = 'betslipPlaceBetButton', }) => { const classes = useStyles({ editorId: dataEditorId }); const theme = useTheme(); return ( < Button elementClasses = { { default: classNames(classes.stakeButton, className), disabled: classes.stakeButtonDisabled, } } disabled = { isDisabled } onClick = { onClick } style = { { padding: 0, } } dataEditorId = { dataEditorId } > { isLoading ? ( < div className = { classes.loaderContainer } > < ButtonLoader color = { theme.brandButton.color } /> < /div> ) : ( children ) } < /Button> ); }; StakeInputButton.propTypes = { dataEditorId: PropTypes.string, }; export default StakeInputButton; ``` ,This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it. ### Before ```ts // In react 19 default props should be replaced with js default function parameters import React from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { makeStyles } from '@material-ui/styles'; import classNames from 'classnames'; import Button from '../../../components/controls/Button'; import { selectors as betsSelectors } from '../../../redux/ducks/bets'; import useOfflineBooking from '../hooks/useOfflineBooking'; const useStyles = makeStyles({ bookingButton: { width: '100%', fontWeight: 600, }, }); const BookingCodeBookButton = ({ className, dataEditorId }) => { const { makeBooking } = useOfflineBooking(); const { t } = useTranslation(); const classes = useStyles(); const selectionsValid = useSelector(betsSelectors.selectSelectionsValid); return ( < Button className = { classNames(classes.bookingButton, className) } disabled = {!selectionsValid } onClick = { () => (selectionsValid ? makeBooking() : null) } dataEditorId = { dataEditorId } > { t('Book') } < /Button> ); }; BookingCodeBookButton.propTypes = { className: PropTypes.string, dataEditorId: PropTypes.string, }; BookingCodeBookButton.defaultProps = { className: null, dataEditorId: 'betslipShareButton', }; export default BookingCodeBookButton; ``` ### After ```ts import React from 'react'; import PropTypes from 'prop-types'; import { useSelector } from 'react-redux'; import { useTranslation } from 'react-i18next'; import { makeStyles } from '@material-ui/styles'; import classNames from 'classnames'; import Button from '../../../components/controls/Button'; import { selectors as betsSelectors } from '../../../redux/ducks/bets'; import useOfflineBooking from '../hooks/useOfflineBooking'; const useStyles = makeStyles({ bookingButton: { width: '100%', fontWeight: 600, }, }); const BookingCodeBookButton = ({ className = null, dataEditorId = 'betslipShareButton', }) => { const { makeBooking } = useOfflineBooking(); const { t } = useTranslation(); const classes = useStyles(); const selectionsValid = useSelector(betsSelectors.selectSelectionsValid); return ( < Button className = { classNames(classes.bookingButton, className) } disabled = {!selectionsValid } onClick = { () => (selectionsValid ? makeBooking() : null) } dataEditorId = { dataEditorId } > { t('Book') } < /Button> ); }; BookingCodeBookButton.propTypes = { className: PropTypes.string, dataEditorId: PropTypes.string, }; export default BookingCodeBookButton; ``` ,This codemod turns X into Y. It also does Z. Note: this is a contrived example. Please modify it. ### Before ```ts // do not add new parameter if default props exist but is not defined in function parameters import React from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import { makeStyles, useTheme } from '@material-ui/styles'; import ButtonArrow from '../../../../components/controls/ButtonArrow'; import SliderPoints from '../../../../components/controls/SliderPoints'; import BetSlipBonusesSlider from '../../BetSlipBonusesSlider'; import BetSlipEmptyBlock from '../../BetSlipTable/BetSlipEmptyBlock'; const useStyles = makeStyles((theme) => ({ bonusesListContainer: { background: theme.bonusPopup.background, color: theme.bonusPopup.color, paddingBottom: 20, overflowY: 'auto', boxSizing: 'border-box', }, points: { maxWidth: 200, margin: '0 auto', }, topLine: { marginBottom: 8, padding: '8px 16px', }, betSlipEmptyBlock: { minHeight: 275, }, })); const BetSlipBonusesListBase = ({ slides, currentSlide, setCurrentSlide, onCloseButtonClick, className, maxHeight, }) => { const theme = useTheme(); const classes = useStyles(); const { t } = useTranslation(); const arrowButtonBackground = theme.bonusPopup.background; return ( < div className = { `${classes.bonusesListContainer} ${className}` } style = { { maxHeight } } > < div className = { classes.topLine } > < ButtonArrow backgroundColor = { arrowButtonBackground } label = { t('Back') } onClick = { onCloseButtonClick } size = { 32 } direction = 'left' / > < /div> { slides.length > 0 ? ( < > < BetSlipBonusesSlider items = { slides } currentSlide = { currentSlide } setCurrentSlide = { setCurrentSlide } /> { !!slides.length && ( < div className = { classes.points } > < SliderPoints count = { slides.length } activeIndex = { currentSlide } color = { theme.bonusPopup.color } activeColor = { theme.bonusPopup.color } /> < /div> ) } < /> ) : ( < BetSlipEmptyBlock text = { t('No available Bonuses at this moment') } className = { classes.betSlipEmptyBlock } /> ) } < /div> ); }; BetSlipBonusesListBase.propTypes = { className: PropTypes.string, placeholder: PropTypes.string, // for widgets showBonusesForBet: PropTypes.string, toggleChooseBonusBlock: PropTypes.func.isRequired, onUseBonus: PropTypes.func.isRequired, onActivateBonus: PropTypes.func.isRequired, availableBonusesIds: PropTypes.arrayOf(PropTypes.string), bonuses: PropTypes.objectOf(PropTypes.shape({})).isRequired, }; BetSlipBonusesListBase.defaultProps = { placeholder: null, className: null, showBonusesForBet: null, availableBonusesIds: null, }; export default BetSlipBonusesListBase; ``` ### After ```ts import React from 'react'; import PropTypes from 'prop-types'; import { useTranslation } from 'react-i18next'; import { makeStyles, useTheme } from '@material-ui/styles'; import ButtonArrow from '../../../../components/controls/ButtonArrow'; import SliderPoints from '../../../../components/controls/SliderPoints'; import BetSlipBonusesSlider from '../../BetSlipBonusesSlider'; import BetSlipEmptyBlock from '../../BetSlipTable/BetSlipEmptyBlock'; const useStyles = makeStyles((theme) => ({ bonusesListContainer: { background: theme.bonusPopup.background, color: theme.bonusPopup.color, paddingBottom: 20, overflowY: 'auto', boxSizing: 'border-box', }, points: { maxWidth: 200, margin: '0 auto', }, topLine: { marginBottom: 8, padding: '8px 16px', }, betSlipEmptyBlock: { minHeight: 275, }, })); const BetSlipBonusesListBase = ({ slides, currentSlide, setCurrentSlide, onCloseButtonClick, className = null, maxHeight, }) => { const theme = useTheme(); const classes = useStyles(); const { t } = useTranslation(); const arrowButtonBackground = theme.bonusPopup.background; return ( < div className = { `${classes.bonusesListContainer} ${className}` } style = { { maxHeight } } > < div className = { classes.topLine } > < ButtonArrow backgroundColor = { arrowButtonBackground } label = { t('Back') } onClick = { onCloseButtonClick } size = { 32 } direction = 'left' / > < /div> { slides.length > 0 ? ( < > < BetSlipBonusesSlider items = { slides } currentSlide = { currentSlide } setCurrentSlide = { setCurrentSlide } /> { !!slides.length && ( < div className = { classes.points } > < SliderPoints count = { slides.length } activeIndex = { currentSlide } color = { theme.bonusPopup.color } activeColor = { theme.bonusPopup.color } /> < /div> ) } < /> ) : ( < BetSlipEmptyBlock text = { t('No available Bonuses at this moment') } className = { classes.betSlipEmptyBlock } /> ) } < /div> ); }; BetSlipBonusesListBase.propTypes = { className: PropTypes.string, placeholder: PropTypes.string, // for widgets showBonusesForBet: PropTypes.string, toggleChooseBonusBlock: PropTypes.func.isRequired, onUseBonus: PropTypes.func.isRequired, onActivateBonus: PropTypes.func.isRequired, availableBonusesIds: PropTypes.arrayOf(PropTypes.string), bonuses: PropTypes.objectOf(PropTypes.shape({})).isRequired, }; export default BetSlipBonusesListBase; ```
This codemods designed to facilitate the migration of your project from React Router to version 7. Each codemod targets specific changes and improvements introduced in React Router v7, ensuring a smoother transition. ## Included Codemods The following codemods are included in this recipe: 1. **[`react-router/7/relative-links`](https://codemod.com/registry/react-router-7-relative-links)** Updates relative link paths to comply with v7 standards. 2. **[`react-router/7/add_v7_relativeSplatPath_Flag`](https://codemod.com/registry/react-router-7-add_v7_relativeSplatPath_Flag)** Adds the `relativeSplatPath` flag to routes to support relative splat behavior. 3. **[`react-router/7/errorfirst-mutation-reorder`](https://codemod.com/registry/react-router-7-errorfirst-mutation-reorder)** Reorders error-first mutation signatures for compatibility with v7. 4. **[`react-router/7/form-methods-post-get-to-uppercase`](https://codemod.com/registry/react-router-7-form-methods-post-get-to-uppercase)** Converts form method strings (`post`, `get`) to uppercase as required by v7. 5. **[`react-router/7/route-wildcard-to-nested`](https://codemod.com/registry/react-router-7-route-wildcard-to-nested)** Transforms route wildcards into nested routes for improved routing management. 6. **[`react-router/7/add_v7_startTransition_Flag`](https://codemod.com/registry/react-router-7-add-v7-startTransition-flag)** Introduces the `startTransition` flag to enhance transitions in routing. 7. **[`react-router/7/add_v7_fetcherPersist_Flag`](https://codemod.com/registry/react-router-7-add_v7_fetcherPersist_Flag)** Adds the `fetcherPersist` flag to improve data fetching mechanisms. 8. **[`react-router/7/add_v7_normalizeFormMethod`](https://codemod.com/registry/react-router-7-add_v7_normalizeFormMethod)** Normalizes form methods to align with v7 conventions. 9. **[`react-router/7/add_v7_partialHydration_Flag`](https://codemod.com/registry/react-router-7-add_v7_partialHydration_Flag)** Integrates the `partialHydration` flag to support enhanced hydration strategies. 10. **[`react-router/7/add_v7_skipActionStatusRevalidation_Flag`](https://codemod.com/registry/react-router-7-add_v7_skipActionStatusRevalidation_Flag)** Adds the `skipActionStatusRevalidation` flag for improved action handling. ---
Move DOM APIs from react to react-dom
This codemod updates imports of `StaticRouter` to use the `react-router-dom/server` package instead of `react-router-dom`, in line with updated React Router requirements. ### Before ```tsx import { BrowserRouter, Route, StaticRouter } from "react-router-dom"; ``` ### After ```tsx import { BrowserRouter, Route } from "react-router-dom"; import { StaticRouter } from "react-router-dom/server"; ``` This codemod ensures compatibility with the latest React Router version by splitting `StaticRouter` imports into the correct package. Other imports from `react-router-dom` remain unaffected.
Reorder React component methods to match eslint-plugin-react sort-comp rule
In v7 the react-router and react-router-dom packages are combined so this codemod import everything directly from "react-router" except for the RouterProvider exception. ### Before ```ts import { BrowserRouter, Routes, Route, useLocation, Link, } from 'react-router-dom'; import { RouterProvider } from 'react-router-dom'; ``` ### After ```ts import { BrowserRouter, Routes, Route, useLocation, Link } from 'react-router'; import { RouterProvider } from 'react-router/dom'; ```
Transform React components using Material UI JSS APIs (e.g., makeStyles/withStyles/createStyles) into strongly typed `tss-react` hook-based styling (`makeStyles` from `tss-react/mui`) in TypeScript React codebases, improving maintainability and type safety while modernizing legacy styling patterns.
No description available
Run this codemod to replace `Router` using `hashHistory` to `HashRouter` in v4.
This codemod updates `Switch` components to `Routes` in React Router, in line with React Router v6 and newer. It also adjusts the imports, replacing `Switch` with `Routes` in `react-router-dom` import statements. ### Before ```tsx import { BrowserRouter, Route, Switch } from "react-router-dom"; <Switch> <Route path="/home" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> </Switch> ``` ### After ```tsx import { BrowserRouter, Route, Routes } from "react-router-dom"; <Routes> <Route path="/home" element={<HomePage />} /> <Route path="/about" element={<AboutPage />} /> </Routes> ``` This codemod modernizes routing logic by using `Routes` instead of `Switch`, aligning your code with the latest practices in React Router.
Replace getDOMNode() with React.findDOMNode()
Build your own codemod and share it with the community.