Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
edb6171
refactor repo
mohab-sameh Apr 9, 2026
0555650
add create-element-to-jsx
mohab-sameh Apr 10, 2026
686746d
remaining codemods
mohab-sameh Apr 10, 2026
4768620
port react-to-react-dom
mohab-sameh Apr 10, 2026
0ff9903
fix disparities
mohab-sameh Apr 14, 2026
e765020
fix create-element-to-jsx
mohab-sameh Apr 14, 2026
18482f2
fix pure-component
mohab-sameh Apr 14, 2026
ad5bf85
fix create-element-to-jsx
mohab-sameh Apr 14, 2026
f9831c7
fix codemods
mohab-sameh Apr 14, 2026
be9fd4b
fix find-dom-node
mohab-sameh Apr 14, 2026
5a00e5f
fix pure-render-mixin
mohab-sameh Apr 14, 2026
362e0c3
improve sort-comp
mohab-sameh Apr 14, 2026
2eaaa23
clean up tests
mohab-sameh Apr 15, 2026
22cc0ae
fix use-form-state
mohab-sameh Apr 15, 2026
f0d54da
revert replace-act-import "improvement"
mohab-sameh Apr 15, 2026
24417e6
fix `replace-string-ref`
mohab-sameh Apr 15, 2026
4a9df82
improve `use-context-hook`
mohab-sameh Apr 15, 2026
0c02788
improve replace-string-ref
mohab-sameh Apr 15, 2026
19c9408
fix replace-act-import migrate all named act imports
mohab-sameh Apr 15, 2026
422d89f
fix issues
mohab-sameh Apr 15, 2026
e785182
refactor repo
mohab-sameh Apr 15, 2026
b6063dd
Merge main, resolve conflicts in favor of codemods/ restructure
mohab-sameh Apr 15, 2026
2e3b434
update docs
mohab-sameh Apr 15, 2026
b1a0069
add migration recipe
mohab-sameh Apr 15, 2026
9f24bca
update codemod names
mohab-sameh Apr 15, 2026
ca4c98e
setup changesets
mohab-sameh Apr 15, 2026
03ea486
fix regressions
mohab-sameh Apr 16, 2026
2e307f8
fix(replace-act-import): broaden workflow include/exclude globs
alexbit-codemod Apr 17, 2026
507c113
test cal.com
mohab-sameh Apr 17, 2026
22b281a
fix copilot issues
mohab-sameh Apr 17, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions .changeset/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Changesets

Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
with multi-package repos, or single-package repos to help you version and publish your code. You can
find the full documentation for it [in the readme](https://github.com/changesets/changesets/blob/main/packages/changesets-cli/README.md)

It is used by the repository to track versioning and release codemods.

## Adding a changeset

Run `pnpm changeset` to create a new changeset for your changes.
15 changes: 15 additions & 0 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.1.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"privatePackages": {
"version": false,
"tag": false
}
}
48 changes: 48 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI

on:
push:
pull_request:

jobs:
docs-and-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.14.2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run lint

active:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.14.2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm run test:active
- run: pnpm run check-types:active

legacy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
version: 9.14.2
- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The legacy CI job runs pnpm run test:legacy without installing dependencies, which will fail on a clean runner. Add an install step (e.g. pnpm install --frozen-lockfile) before running the legacy tests.

Suggested change
cache: pnpm
cache: pnpm
- run: pnpm install --frozen-lockfile

Copilot uses AI. Check for mistakes.
- run: pnpm run test:legacy
70 changes: 70 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Release

on:
push:
branches:
- main

concurrency: ${{ github.workflow }}-${{ github.ref }}

permissions:
id-token: write
contents: write
pull-requests: write

jobs:
release:
name: Release
runs-on: ubuntu-latest
outputs:
published: ${{ steps.changesets.outputs.published }}
changed_dirs: ${{ steps.tag.outputs.changed_dirs }}
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Create Release PR or Publish
id: changesets
uses: changesets/action@v1
with:
version: pnpm version-packages
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Tag released versions
if: steps.changesets.outputs.hasChangesets == 'false'
id: tag
run: bash scripts/tag-and-publish.sh

publish:
name: Publish ${{ matrix.dir }}
needs: release
if: needs.release.outputs.changed_dirs != '[]' && needs.release.outputs.changed_dirs != ''
runs-on: ubuntu-latest
strategy:
matrix:
dir: ${{ fromJson(needs.release.outputs.changed_dirs) }}
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4

- uses: actions/setup-node@v4
with:
node-version: 20
cache: pnpm

- run: pnpm install --frozen-lockfile

- name: Publish codemod
uses: codemod/publish-action@v1
with:
path: ${{ matrix.dir }}
60 changes: 60 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Contributing

Thanks for your interest in contributing to react-codemod!

## Development setup

```bash
# Install dependencies
pnpm install

# Run all tests
pnpm test

# Type-check all codemods
pnpm check-types
```

## Making changes

1. Create a branch from `main`.
2. Make your changes and add or update tests.
3. Run `pnpm test` and `pnpm check-types` to verify everything passes.
4. Add a changeset (see below).
5. Open a pull request.

## Adding a changeset

This repo uses [Changesets](https://github.com/changesets/changesets) for versioning and releases. Every PR that changes a codemod must include a changeset.

```bash
pnpm changeset
```

Follow the prompts to:
1. Select the affected codemod(s).
2. Choose the semver bump type — **patch** for bug fixes, **minor** for new features, **major** for breaking changes.
3. Write a short summary of the change.

This creates a markdown file in `.changeset/` that should be committed with your PR.

## Release workflow

1. Merge a PR with one or more changesets into `main`.
2. CI automatically opens a **Version Packages** PR that bumps versions in `package.json` and `codemod.yaml`.
3. Merge the version PR — git tags are created and the updated codemods are published to the Codemod registry.

## Adding a new codemod

Each codemod lives in its own directory under `codemods/jssg/`:

```
codemods/jssg/<name>/
scripts/codemod.ts # Codemod logic (jssg / ast-grep)
tests/ # Input/expected test fixtures
codemod.yaml # Codemod manifest
workflow.yaml # Execution workflow
package.json
```

Use an existing codemod as a reference when creating a new one.
32 changes: 32 additions & 0 deletions LEGACY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Legacy Codemods

The following jscodeshift-based codemods from the original [`react-codemod`](https://github.com/reactjs/react-codemod) project are available under [`codemods/legacy/transforms/`](./codemods/legacy/transforms/).

These codemods are preserved for compatibility and can be run directly with jscodeshift.

## Catalog

- [`create-element-to-jsx`](./codemods/legacy/transforms/create-element-to-jsx.js) — convert `React.createElement` calls to JSX
- [`error-boundaries`](./codemods/legacy/transforms/error-boundaries.js) — rename `unstable_handleError` to `componentDidCatch`
- [`findDOMNode`](./codemods/legacy/transforms/findDOMNode.js) — update `getDOMNode()` calls to `React.findDOMNode()`
- [`manual-bind-to-arrow`](./codemods/legacy/transforms/manual-bind-to-arrow.js) — convert manual function bindings to arrow functions
- [`pure-component`](./codemods/legacy/transforms/pure-component.js) — convert render-only class components to functional components
- [`pure-render-mixin`](./codemods/legacy/transforms/pure-render-mixin.js) — remove `PureRenderMixin` and inline `shouldComponentUpdate`
- [`React-DOM-to-react-dom-factories`](./codemods/legacy/transforms/React-DOM-to-react-dom-factories.js) — convert `React.DOM.div(...)` to `React.createElement('div', ...)`
- [`ReactNative-View-propTypes`](./codemods/legacy/transforms/ReactNative-View-propTypes.js) — replace `View.propTypes` with `ViewPropTypes`
- [`react-to-react-dom`](./codemods/legacy/transforms/react-to-react-dom.js) — update code for the `react` / `react-dom` package split
- [`remove-context-provider`](./codemods/legacy/transforms/remove-context-provider.ts) — convert `Context.Provider` elements to `Context`
- [`remove-forward-ref`](./codemods/legacy/transforms/remove-forward-ref.ts) — remove usages of `forwardRef`
- [`rename-unsafe-lifecycles`](./codemods/legacy/transforms/rename-unsafe-lifecycles.js) — add `UNSAFE_` prefix to deprecated lifecycle hooks
- [`sort-comp`](./codemods/legacy/transforms/sort-comp.js) — enforce React component method ordering
- [`update-react-imports`](./codemods/legacy/transforms/update-react-imports.js) — remove redundant React imports and convert to named imports
- [`class`](./codemods/legacy/transforms/class.js) — convert `React.createClass` calls to ES6 classes

## Running

From `codemods/legacy/`:

```bash
pnpm install
pnpm test
```
39 changes: 39 additions & 0 deletions PARITY_STATUS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Parity Status

Last updated: 2026-04-15

Status meanings:

- `Certified`: replacement-grade confidence. Tests are green, public test posture is portable, and there are no known logic gaps versus the original jscodeshift codemod. May include safe extensions on edge cases the original did not handle, as long as original behavior remains unbroken.
- `Legacy`: available as a jscodeshift codemod under `codemods/legacy/`. Not yet ported to JSSG.

## JSSG Codemods

| Codemod | Original Source | Status | Notes |
| --- | --- | --- | --- |
| `replace-use-form-state` | `replace-use-form-state.ts` | `Certified` | Full fixture coverage plus multi-import regression tests are green. Collection-wide replacement on matching `react-dom` imports fixes a real parity gap. |
| `replace-act-import` | `replace-act-import.ts` | `Certified` | Full fixture coverage plus multi-import regression tests. Mixed test-utils partial-removal path is a safe extension. |
| `replace-string-ref` | `replace-string-ref.ts` | `Certified` | Full fixture coverage plus namespace/default-export/multi-ref tests are green. Direct-superclass guard restores intended behavior. |
| `replace-reactdom-render` | `replace-reactdom-render.ts` | `Certified` | Full fixture coverage plus multi-alias regression tests are green. |
| `react-proptypes-to-prop-types` | `React-PropTypes-to-prop-types.js` | `Certified` | Full original fixture surface is green. No JSSG-specific rollout blocker found. |
| `use-context-hook` | `use-context-hook.ts` | `Certified` | Full fixture coverage plus multi-import regression tests are green. |

## Legacy Codemods

These codemods are available as jscodeshift transforms under [`codemods/legacy/transforms/`](./codemods/legacy/transforms/):

- `class`
- `create-element-to-jsx`
- `error-boundaries`
- `findDOMNode`
- `manual-bind-to-arrow`
- `pure-component`
- `pure-render-mixin`
- `React-DOM-to-react-dom-factories`
- `ReactNative-View-propTypes`
- `react-to-react-dom`
- `remove-context-provider`
- `remove-forward-ref`
- `rename-unsafe-lifecycles`
- `sort-comp`
- `update-react-imports`
Loading
Loading