
React Modernization
- 10k installs
- 38.3k repo stars
- Updated July 22, 2026
- wshobson/agents
react-modernization is an agent skill that Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migr.
About
Upgrade React applications to latest versions migrate from class components to hooks and adopt concurrent features Use when modernizing React codebases migrating to React Hooks or upgrading to latest React versions name react-modernization description Upgrade React applications to latest versions migrate from class components to hooks and adopt concurrent features Use when modernizing React codebases migrating to React Hooks or upgrading to latest React versions React Modernization Master React version upgrades class to hooks migration concurrent features adoption and codemods for automated transformation When to Use This Skill Upgrading React applications to latest versions Migrating class components to functional components with hooks Adopting concurrent React features Suspense transitions Applying codemods for automated refactoring Modernizing state management patterns Updating to TypeScript Improving performance with React 18 features Version Upgrade Path React 16 17 18 Breaking Changes by Version React 17 Event delegation changes No event pooling Effect cleanup timing JSX transform no React import needed React 18 Automatic batching Concurrent rendering Strict Mode changes dou.
- Upgrading React applications to latest versions
- Migrating class components to functional components with hooks
- Adopting concurrent React features (Suspense, transitions)
- Applying codemods for automated refactoring
- Modernizing state management patterns
React Modernization by the numbers
- 10,041 all-time installs (skills.sh)
- +200 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #85 of 2,184 Testing & QA skills by installs in the Skillselion catalog
- Security screen: MEDIUM risk (skills.sh audit)
- Data as of Jul 28, 2026 (Skillselion catalog sync)
react-modernization capabilities & compatibility
- Capabilities
- upgrading react applications to latest versions · migrating class components to functional compone · adopting concurrent react features (suspense, tr · applying codemods for automated refactoring · modernizing state management patterns
- Use cases
- documentation
What react-modernization says it does
--- name: react-modernization description: Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features.
Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
--- # React Modernization Master React version upgrades, class to hooks migration, concurrent features adoption, and codemods for automated transformation.
Read that file for the full pattern library.
npx skills add https://github.com/wshobson/agents --skill react-modernizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 10k |
|---|---|
| repo stars | ★ 38.3k |
| Security audit | 2 / 3 scanners passed |
| Last updated | July 22, 2026 |
| Repository | wshobson/agents ↗ |
What problem does react-modernization solve for developers using this skill?
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to la
Who is it for?
Developers who need react-modernization patterns described in the cached skill documentation.
Skip if: Skip when docs are empty or the task is outside the skill's documented scope.
When should I use this skill?
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to la
What you get
Actionable workflows and conventions from SKILL.md for react-modernization.
- Codemod-transformed source files
- Migration command reference
By the numbers
- Documents at least 4 react-codemod jscodeshift transforms including rename-unsafe-lifecycles, update-react-imports, and
Files
React Modernization
Master React version upgrades, class to hooks migration, concurrent features adoption, and codemods for automated transformation.
When to Use This Skill
- Upgrading React applications to latest versions
- Migrating class components to functional components with hooks
- Adopting concurrent React features (Suspense, transitions)
- Applying codemods for automated refactoring
- Modernizing state management patterns
- Updating to TypeScript
- Improving performance with React 18+ features
Version Upgrade Path
React 16 → 17 → 18
Breaking Changes by Version:
React 17:
- Event delegation changes
- No event pooling
- Effect cleanup timing
- JSX transform (no React import needed)
React 18:
- Automatic batching
- Concurrent rendering
- Strict Mode changes (double invocation)
- New root API
- Suspense on server
Class to Hooks Migration
State Management
// Before: Class component
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
count: 0,
name: "",
};
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
// After: Functional component with hooks
function Counter() {
const [count, setCount] = useState(0);
const [name, setName] = useState("");
const increment = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}Lifecycle Methods to Hooks
// Before: Lifecycle methods
class DataFetcher extends React.Component {
state = { data: null, loading: true };
componentDidMount() {
this.fetchData();
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
this.fetchData();
}
}
componentWillUnmount() {
this.cancelRequest();
}
fetchData = async () => {
const data = await fetch(`/api/${this.props.id}`);
this.setState({ data, loading: false });
};
cancelRequest = () => {
// Cleanup
};
render() {
if (this.state.loading) return <div>Loading...</div>;
return <div>{this.state.data}</div>;
}
}
// After: useEffect hook
function DataFetcher({ id }) {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let cancelled = false;
const fetchData = async () => {
try {
const response = await fetch(`/api/${id}`);
const result = await response.json();
if (!cancelled) {
setData(result);
setLoading(false);
}
} catch (error) {
if (!cancelled) {
console.error(error);
}
}
};
fetchData();
// Cleanup function
return () => {
cancelled = true;
};
}, [id]); // Re-run when id changes
if (loading) return <div>Loading...</div>;
return <div>{data}</div>;
}Context and HOCs to Hooks
// Before: Context consumer and HOC
const ThemeContext = React.createContext();
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
return (
<button style={{ background: this.context.theme }}>
{this.props.children}
</button>
);
}
}
// After: useContext hook
function ThemedButton({ children }) {
const { theme } = useContext(ThemeContext);
return <button style={{ background: theme }}>{children}</button>;
}
// Before: HOC for data fetching
function withUser(Component) {
return class extends React.Component {
state = { user: null };
componentDidMount() {
fetchUser().then((user) => this.setState({ user }));
}
render() {
return <Component {...this.props} user={this.state.user} />;
}
};
}
// After: Custom hook
function useUser() {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUser().then(setUser);
}, []);
return user;
}
function UserProfile() {
const user = useUser();
if (!user) return <div>Loading...</div>;
return <div>{user.name}</div>;
}React 18 Concurrent Features
New Root API
// Before: React 17
import ReactDOM from "react-dom";
ReactDOM.render(<App />, document.getElementById("root"));
// After: React 18
import { createRoot } from "react-dom/client";
const root = createRoot(document.getElementById("root"));
root.render(<App />);Automatic Batching
// React 18: All updates are batched
function handleClick() {
setCount((c) => c + 1);
setFlag((f) => !f);
// Only one re-render (batched)
}
// Even in async:
setTimeout(() => {
setCount((c) => c + 1);
setFlag((f) => !f);
// Still batched in React 18!
}, 1000);
// Opt out if needed
import { flushSync } from "react-dom";
flushSync(() => {
setCount((c) => c + 1);
});
// Re-render happens here
setFlag((f) => !f);
// Another re-renderTransitions
import { useState, useTransition } from "react";
function SearchResults() {
const [query, setQuery] = useState("");
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleChange = (e) => {
// Urgent: Update input immediately
setQuery(e.target.value);
// Non-urgent: Update results (can be interrupted)
startTransition(() => {
setResults(searchResults(e.target.value));
});
};
return (
<>
<input value={query} onChange={handleChange} />
{isPending && <Spinner />}
<Results data={results} />
</>
);
}Suspense for Data Fetching
import { Suspense } from "react";
// Resource-based data fetching (with React 18)
const resource = fetchProfileData();
function ProfilePage() {
return (
<Suspense fallback={<Loading />}>
<ProfileDetails />
<Suspense fallback={<Loading />}>
<ProfileTimeline />
</Suspense>
</Suspense>
);
}
function ProfileDetails() {
// This will suspend if data not ready
const user = resource.user.read();
return <h1>{user.name}</h1>;
}
function ProfileTimeline() {
const posts = resource.posts.read();
return <Timeline posts={posts} />;
}Additional patterns and templates
More detailed templates and worked examples live in references/details.md. Read that file for the full pattern library.
react-modernization — additional patterns and templates
Codemods for Automation
Run React Codemods
# Rename unsafe lifecycle methods
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js src/
# Update React imports (React 17+)
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/update-react-imports.js src/
# Add error boundaries
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/error-boundaries.js src/
# For TypeScript files
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --parser=tsx src/
# Dry run to preview changes
npx jscodeshift -t https://raw.githubusercontent.com/reactjs/react-codemod/master/transforms/rename-unsafe-lifecycles.js --dry --print src/
# Class to Hooks (third-party)
npx codemod react/hooks/convert-class-to-function src/Custom Codemod Example
// custom-codemod.js
module.exports = function (file, api) {
const j = api.jscodeshift;
const root = j(file.source);
// Find setState calls
root
.find(j.CallExpression, {
callee: {
type: "MemberExpression",
property: { name: "setState" },
},
})
.forEach((path) => {
// Transform to useState
// ... transformation logic
});
return root.toSource();
};
// Run: jscodeshift -t custom-codemod.js src/Performance Optimization
useMemo and useCallback
function ExpensiveComponent({ items, filter }) {
// Memoize expensive calculation
const filteredItems = useMemo(() => {
return items.filter((item) => item.category === filter);
}, [items, filter]);
// Memoize callback to prevent child re-renders
const handleClick = useCallback((id) => {
console.log("Clicked:", id);
}, []); // No dependencies, never changes
return <List items={filteredItems} onClick={handleClick} />;
}
// Child component with memo
const List = React.memo(({ items, onClick }) => {
return items.map((item) => (
<Item key={item.id} item={item} onClick={onClick} />
));
});Code Splitting
import { lazy, Suspense } from "react";
// Lazy load components
const Dashboard = lazy(() => import("./Dashboard"));
const Settings = lazy(() => import("./Settings"));
function App() {
return (
<Suspense fallback={<Loading />}>
<Routes>
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/settings" element={<Settings />} />
</Routes>
</Suspense>
);
}TypeScript Migration
// Before: JavaScript
function Button({ onClick, children }) {
return <button onClick={onClick}>{children}</button>;
}
// After: TypeScript
interface ButtonProps {
onClick: () => void;
children: React.ReactNode;
}
function Button({ onClick, children }: ButtonProps) {
return <button onClick={onClick}>{children}</button>;
}
// Generic components
interface ListProps<T> {
items: T[];
renderItem: (item: T) => React.ReactNode;
}
function List<T>({ items, renderItem }: ListProps<T>) {
return <>{items.map(renderItem)}</>;
}Migration Checklist
### Pre-Migration
- [ ] Update dependencies incrementally (not all at once)
- [ ] Review breaking changes in release notes
- [ ] Set up testing suite
- [ ] Create feature branch
### Class → Hooks Migration
- [ ] Identify class components to migrate
- [ ] Start with leaf components (no children)
- [ ] Convert state to useState
- [ ] Convert lifecycle to useEffect
- [ ] Convert context to useContext
- [ ] Extract custom hooks
- [ ] Test thoroughly
### React 18 Upgrade
- [ ] Update to React 17 first (if needed)
- [ ] Update react and react-dom to 18
- [ ] Update @types/react if using TypeScript
- [ ] Change to createRoot API
- [ ] Test with StrictMode (double invocation)
- [ ] Address concurrent rendering issues
- [ ] Adopt Suspense/Transitions where beneficial
### Performance
- [ ] Identify performance bottlenecks
- [ ] Add React.memo where appropriate
- [ ] Use useMemo/useCallback for expensive operations
- [ ] Implement code splitting
- [ ] Optimize re-renders
### Testing
- [ ] Update test utilities (React Testing Library)
- [ ] Test with React 18 features
- [ ] Check for warnings in console
- [ ] Performance testingRelated skills
How it compares
Pick react-modernization over generic refactor skills when the codebase specifically needs official React codemods for class-to-hooks and lifecycle migrations.
FAQ
What does react-modernization do?
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
When should I use react-modernization?
Upgrade React applications to latest versions, migrate from class components to hooks, and adopt concurrent features. Use when modernizing React codebases, migrating to React Hooks, or upgrading to latest React versions.
Is react-modernization safe to install?
Review the Security Audits panel on this page before installing in production.