React Modernization

SkillDev tools

This is a skill for upgrading React applications. It helps an AI agent move a project to a newer React version, convert class components to hooks, adopt concurrent features, and run codemods for automated transformation. The react claude skill gives the agent a structured way to handle these changes instead of improvising each one.

Use React Modernization in Claude, ChatGPT or Ahel Desktop

Free. Sign in, add React Modernization and connect your AI. About a minute.

Also: Claude Code · Cursor · Codex

Then ask your AI: use the React Modernization skill

Details

Instructions available. Your AI can read the instructions. Execution depends on the setup they require.

Have a React project with its dependencies and build setup in place.

React ModernizationStart free

What your AI can do with it

  • Upgrade a React app to a newer major version
  • Migrate class components to function components with hooks
  • Adopt concurrent features in an existing app
  • Run codemods to automate repetitive transformations
  • Plan an upgrade path across React versions

Getting started

  1. Have a React project with its dependencies and build setup in place.
  2. Add the react-modernization skill to your agent's available skills.
  3. Point the agent at the project and state which upgrade or migration you want.
  4. Review the changes the agent proposes before applying them.

What this skill tells your AI

The instructions your AI receives, as published by sickn33/agentic-awesome-skills in skills/react-modernization/SKILL.md and read by ahel’s review.

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-render

Transitions

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.

Signals

GitHub stars
47k
Forks
7k
Last commit
Sep 2026

Questions

Can it migrate class components to hooks?
Yes. Class to hooks migration is one of the transformations this skill covers, alongside version upgrades and concurrent features.
Does it use codemods?
Yes. Codemods for automated transformation are part of what the skill handles.
Which React versions does it support?
The skill covers React version upgrades generally, but it does not list specific version numbers.
Does it apply changes automatically?
The skill guides the agent through upgrades and codemods, but it does not state whether changes are applied without review.
Advanced
Item type
skill
Key
react-modernization
Source
github.com/sickn33/agentic-awesome-skills