npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@thinksharpe/react-compiler-unmemo

v0.6.1

Published

Remove useMemo and useCallback hooks from React codebases to leverage React Compiler automatic optimization

Readme

react-compiler-unmemo

License: MIT Node.js Tests

A codemod that removes useMemo and useCallback from your React codebase so you can adopt React Compiler without the manual cleanup.

Note: React Compiler works fine with existing manual memoization — it preserves and layers on top of it. Removing hooks is optional for cleanliness and readability, but not required for performance. Use this tool to declutter legacy code. Always preview with --dry-run and type-check afterward.

Quick Start

npx react-compiler-unmemo ./my-react-app

This previews all changes without modifying any files (dry-run is the safe default). When you're ready to apply:

npx react-compiler-unmemo ./my-react-app --write

Or clone and run locally:

git clone https://github.com/thinksharpe/react-compiler-unmemo.git
cd react-compiler-unmemo
npm install
node react-compiler-unmemo.mjs ./path/to/your/project

Origin

I tried using Claude Opus 4.5 to write a script that would remove useMemo and useCallback from my codebase, but it kept failing. Claude noticed that sed couldn't handle this kind of complex pattern matching — the nested parentheses, arrow functions, and dependency arrays made it impossible with simple text replacement. So it wrote this script instead.

I like to keep my code as readable as possible, and all those useMemo and useCallback hooks were adding extra complexity. I'm glad they're gone from my codebase now. Hope it helps someone else too.

Before / After

- const value = useMemo(() => computeExpensiveValue(a, b), [a, b]);
+ const value = computeExpensiveValue(a, b);

- const handler = useCallback((e) => doSomething(e), [doSomething]);
+ const handler = (e) => doSomething(e);

- import { useMemo, useCallback, useState } from "react";
+ import { useState } from "react";

Why

  • Cleaner code — less boilerplate, easier to read and maintain
  • Aligns with modern React — React Compiler handles memoization automatically
  • Smaller bundles — unused hook imports are removed
  • Safe to re-run — idempotent, won't touch already-processed files

Usage

# 1. Preview changes (safe default — no files modified)
node react-compiler-unmemo.mjs ./my-app

# 2. Apply changes
node react-compiler-unmemo.mjs ./my-app --write

# 3. Type-check your project
cd ./my-app && npx tsc --noEmit

Options

| Flag | Description | Default | |------|-------------|--------| | (no flag) | Preview changes without writing files | dry-run | | --write | Apply changes to files | off | | --verbose | Log every transformation | off | | --files <glob> | Limit to specific file patterns | src/**/*.{tsx,ts} | | --skip-fix | Skip type annotation repair step | off |

# Only process hooks directory
node react-compiler-unmemo.mjs ./my-app --files "src/hooks/**/*.ts" --write

# app directory
node react-compiler-unmemo.mjs ./my-app --files "app/**/*.{tsx,ts}"

# See every change in detail
node react-compiler-unmemo.mjs ./my-app --verbose

What It Handles

  • useMemo(() => expr, [deps])expr
  • useMemo(() => { return expr; }, [deps])expr
  • useMemo<Type>(...) → strips the generic, restores the type annotation
  • useCallback((params) => body, [deps])(params) => body
  • React.useMemo / React.useCallback variants
  • Multi-line hooks spanning dozens of lines
  • Nested generics like useMemo<ColumnsType<MyType>>()
  • Import cleanup (removes unused useMemo/useCallback from imports)

When NOT to Use

  • You haven't enabled React Compiler yet — without the compiler, removing useMemo/useCallback may cause performance regressions
  • Intentional escape hatches — some hooks are used deliberately to control referential identity for third-party libraries
  • Class component interop — if memoized values are passed to class components that rely on shallow comparison

When in doubt, use --dry-run and review the output.

Post-Migration

Always run your type checker after the migration:

npx tsc --noEmit
# or your project's build command

The tool handles the most common cases automatically, but some things need manual attention:

  • Hooks with // comments inside — the parser may skip or partially transform these. Check the "remaining refs" count in the output.
  • Missing imports — the type fixer adds ColumnsType<T> annotations but may not add the import statement.
  • Dangling as Type casts — if a useCallback had an as React.FC cast, it may need cleanup.
  • Broken IIFEs — complex useMemo bodies with comments may leave a trailing , [deps]) instead of })().

See docs/edge-cases.md for the full list with code examples.

Project Structure

react-compiler-unmemo/
├── react-compiler-unmemo.mjs  # Entry point
├── helpers/
│   ├── remove-hooks.mjs # Core hook removal
│   └── fix-type-annotations.mjs
├── docs/
│   ├── architecture.md  # How it works under the hood
│   └── edge-cases.md    # Known edge cases & fixes
├── package.json
└── README.md

For technical details on the parser and pipeline, see docs/architecture.md.

Contributing

Issues, PRs, and edge-case examples welcome. Please open an issue first for large changes.

If you've run this on a real codebase and hit an edge case, sharing the pattern (even without proprietary code) helps improve the tool for everyone.

Links

License

MIT — see LICENSE