"Help quickly replace the prop type checker in older react projects to map to prop-types"
npm install move-prop-types


A modern, TypeScript-based CLI tool that automatically refactors your React codebase to use the standalone prop-types package instead of the deprecated React.PropTypes. Supports JavaScript, JSX, TypeScript, and TSX files with robust transformation capabilities.
When React v15.5 was released in 2017, PropTypes was deprecated from the core React package and moved to a separate prop-types package. Many legacy React projects still use the old React.PropTypes syntax, which is no longer supported in modern React versions.
This CLI tool automates the migration process by:
- โ
Detecting legacy PropTypes usage - Scans for React.PropTypes patterns
- โ
Removing PropTypes from React imports - Cleans up import { PropTypes } from React
- โ
Adding standalone prop-types import - Adds import PropTypes from 'prop-types'
- โ
Replacing usage patterns - Changes React.PropTypes.string to PropTypes.string
- โ
Handling complex nested patterns - Supports complex PropTypes like PropTypes.arrayOf(PropTypes.shape(...))
- โ
Processing entire codebases - Recursively processes directories and subdirectories
- โ
Installing dependencies - Optionally installs the prop-types package automatically
- โ
TypeScript & JSX Support - Works with .js, .jsx, .ts, and .tsx files
- โ
Advanced Pattern Recognition - Handles complex import patterns and edge cases
bash
npm install -g move-prop-types
or with pnpm
pnpm add -g move-prop-types
or with yarn
yarn global add move-prop-types
`$3
`bash
npm install --save-dev move-prop-types
or with pnpm
pnpm add --save-dev move-prop-types
or with yarn
yarn add --dev move-prop-types
`๐ ๏ธ Usage
`bash
Usage: move-prop-types|mpt [options] [file|folder]Options:
-V, --version output the version number
-I, --install install prop-types package and continue with transformation
-P, --path transform a specific file
-F, --folder transform all .js/.jsx/.ts/.tsx files in a folder (recursive)
-h, --help display help for command
`๐ Examples
$3
`bash
Transform JavaScript/JSX files
mpt -P src/components/UserProfile.jsx
mpt -P src/utils/validators.jsTransform TypeScript/TSX files
mpt -P src/components/UserProfile.tsx
mpt -P src/types/PropTypes.tsTransform with automatic prop-types installation
mpt -I -P src/components/UserProfile.tsxTransform a file with relative path
mpt -P ./components/Header.tsTransform multiple files (run command for each)
mpt -P src/components/Button.jsx
mpt -P src/components/Modal.tsx
mpt -P src/utils/validators.ts
`$3
`bash
Transform all .js/.jsx/.ts/.tsx files in src directory recursively
mpt -F srcTransform entire project with prop-types installation
mpt -I -F .Transform specific subdirectories
mpt -F src/components
mpt -F src/pages
mpt -F src/utilsLarge TypeScript project with automatic dependency installation
mpt -I -F src
`$3
#### Legacy React Project
`bash
1. Install move-prop-types globally
npm install -g move-prop-types2. Navigate to your React project
cd my-react-project3. Install prop-types and transform entire codebase
mpt -I -F src4. Verify changes and test your application
npm test
`#### Migrating Specific Components
`bash
Transform only component files
mpt -F src/componentsTransform only utility files that use PropTypes
mpt -P src/utils/propTypeValidators.js
mpt -P src/hoc/withPropTypes.js
`$3
#### Simple Component Migration
Before transformation:
`javascript
import React, { Component, PropTypes } from 'react';class UserProfile extends Component {
render() {
const { name, email, age, isActive } = this.props;
return (
{name}
Email: {email}
Age: {age}
{isActive && Active User}
);
}
}UserProfile.propTypes = {
name: React.PropTypes.string.isRequired,
email: React.PropTypes.string.isRequired,
age: React.PropTypes.number,
isActive: React.PropTypes.bool
};
UserProfile.defaultProps = {
age: 0,
isActive: false
};
export default UserProfile;
`After transformation:
`javascript
import React, { Component } from 'react';
import PropTypes from 'prop-types';class UserProfile extends Component {
render() {
const { name, email, age, isActive } = this.props;
return (
{name}
Email: {email}
Age: {age}
{isActive && Active User}
);
}
}UserProfile.propTypes = {
name: PropTypes.string.isRequired,
email: PropTypes.string.isRequired,
age: PropTypes.number,
isActive: PropTypes.bool
};
UserProfile.defaultProps = {
age: 0,
isActive: false
};
export default UserProfile;
`#### Complex PropTypes Migration
Before transformation:
`javascript
import React, { PropTypes } from 'react';const DataTable = ({ data, columns, onRowClick, pagination, loading }) => {
// Component implementation
return
DataTable Component;
};DataTable.propTypes = {
data: React.PropTypes.arrayOf(React.PropTypes.object).isRequired,
columns: React.PropTypes.arrayOf(React.PropTypes.shape({
key: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired,
render: React.PropTypes.func,
sortable: React.PropTypes.bool
})).isRequired,
onRowClick: React.PropTypes.func,
pagination: React.PropTypes.oneOfType([
React.PropTypes.bool,
React.PropTypes.shape({
page: React.PropTypes.number,
pageSize: React.PropTypes.number,
total: React.PropTypes.number
})
]),
loading: React.PropTypes.bool
};
export default DataTable;
`After transformation:
`javascript
import React from 'react';
import PropTypes from 'prop-types';const DataTable = ({ data, columns, onRowClick, pagination, loading }) => {
// Component implementation
return
DataTable Component;
};DataTable.propTypes = {
data: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.shape({
key: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
render: PropTypes.func,
sortable: PropTypes.bool
})).isRequired,
onRowClick: PropTypes.func,
pagination: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.shape({
page: PropTypes.number,
pageSize: PropTypes.number,
total: PropTypes.number
})
]),
loading: PropTypes.bool
};
export default DataTable;
`#### Functional Component Migration
Before transformation:
`javascript
import React, { PropTypes } from 'react';function Button({ label, onClick, disabled, variant, size }) {
return (
onClick={onClick}
disabled={disabled}
className={
btn btn-${variant} btn-${size}}
>
{label}
);
}Button.propTypes = {
label: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired,
disabled: React.PropTypes.bool,
variant: React.PropTypes.oneOf(['primary', 'secondary', 'danger']),
size: React.PropTypes.oneOf(['small', 'medium', 'large'])
};
Button.defaultProps = {
disabled: false,
variant: 'primary',
size: 'medium'
};
export default Button;
`After transformation:
`javascript
import React from 'react';
import PropTypes from 'prop-types';function Button({ label, onClick, disabled, variant, size }) {
return (
onClick={onClick}
disabled={disabled}
className={
btn btn-${variant} btn-${size}}
>
{label}
);
}Button.propTypes = {
label: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired,
disabled: PropTypes.bool,
variant: PropTypes.oneOf(['primary', 'secondary', 'danger']),
size: PropTypes.oneOf(['small', 'medium', 'large'])
};
Button.defaultProps = {
disabled: false,
variant: 'primary',
size: 'medium'
};
export default Button;
`#### TypeScript Component Migration
Before transformation:
`typescript
import React, { FC, PropTypes } from 'react';interface MyComponentProps {
title: string;
count?: number;
onClick: (id: number) => void;
}
const MyComponent: FC = ({ title, count = 0, onClick }) => {
return (
{title}
Count: {count}
);
};
MyComponent.propTypes = {
title: React.PropTypes.string.isRequired,
count: React.PropTypes.number,
onClick: React.PropTypes.func.isRequired
};
export default MyComponent;
`After transformation:
`typescript
import React, { FC } from 'react';
import PropTypes from 'prop-types';interface MyComponentProps {
title: string;
count?: number;
onClick: (id: number) => void;
}
const MyComponent: FC = ({ title, count = 0, onClick }) => {
return (
{title}
Count: {count}
);
};
MyComponent.propTypes = {
title: PropTypes.string.isRequired,
count: PropTypes.number,
onClick: PropTypes.func.isRequired
};
export default MyComponent;
`๐๏ธ Features
- TypeScript Support: Built with TypeScript for better reliability and type safety
- Modern Tooling: Uses latest ESLint, Prettier, and build tools
- Comprehensive Testing: Full test suite with unit and integration tests
- Recursive Processing: Handles entire directory structures
- Smart Detection: Only processes files that actually use PropTypes
- Safe Transformations: Preserves existing prop-types imports
- Multiple Import Patterns: Handles various React import styles
- TypeScript Compatibility: Preserves TypeScript syntax, interfaces, and type annotations
- Advanced Pattern Detection: Handles complex PropTypes patterns including middle-position imports
๐งช Development
$3
- Node.js 18+
- pnpm (recommended) or npm$3
`bash
Clone the repository
git clone https://github.com/vish288/move-prop-types.git
cd move-prop-typesInstall dependencies
pnpm installBuild the project
pnpm run buildRun tests
pnpm testRun linting
pnpm run lint
`$3
`
src/
โโโ core.ts # CLI command setup and argument parsing
โโโ helper.ts # Core transformation logic with TypeScript support
โโโ ast-helper.ts # Advanced AST-based transformation (experimental)
โโโ ast-transformer.ts # AST parsing and transformation utilities
โโโ constants.ts # Regular expressions and transformation patterns
โโโ types.ts # TypeScript type definitions
โโโ updateFile.ts # Build utility for adding shebangtest/
โโโ unit/ # Unit tests for individual modules
โ โโโ helper.test.ts
โ โโโ ast-transformer.test.ts
โ โโโ constants.test.ts
โ โโโ core.test.ts
โโโ integration/ # Integration tests for real-world scenarios
โโโ fixtures/ # Test files for various transformation scenarios
`๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature)
5. Open a Pull Request๐ฆ Release Status & NPM Publishing
$3
- โ
v1.0.0 - Stable release with full TypeScript support
- โ
v0.20.1-beta.1 - Beta release with TypeScript support
- ๐ NPM Publishing - Automatic publishing configured
$3
The following GitHub releases are ready but not yet published to npm:
-
v0.20.1-beta.1 (TypeScript support beta)
- v1.0.0 (stable release with TypeScript support)These will be automatically published once the repository maintainer configures the NPM_TOKEN secret.
$3
This repository includes an automated system to:
- โ
Detect missing versions between GitHub releases and npm
- โ
Publish automatically when NPM_TOKEN is configured
- โ
Daily checks for any missing versions
- โ
Manual triggers available via GitHub Actions
docs/NPM_PUBLISHING.md for setup instructions.๐ Requirements
- Node.js: Version 18 or higher
- File Types: Supports
.js, .jsx, .ts, and .tsx files
- React Versions: Compatible with all React versions that used React.PropTypes`If you encounter any issues or have feature requests, please open an issue on GitHub.
This project is licensed under the MIT License - see the LICENSE file for details.
- React team for the smooth transition process
- The community for feedback and contributions
- All users who have helped improve this tool