jsx-slicer
v0.1.0
Published
A command-line tool that automatically refactors large React components into smaller, reusable pieces. It uses AST analysis to safely extract JSX, find duplicate blocks, and infer props without using AI.
Maintainers
Readme
jsx-slicer 🔪
A safe, no‑AI code‑mod that splits a very large JSX file into smaller, reusable components using AST heuristics. It targets repeat JSX structures and big self‑contained blocks, infers props, and rewrites your file with imports + generated components.
Philosophy: be conservative so we don't break behavior. We only extract blocks that look safe (no hooks inside, no setState setters captured).
Quickstart
Install:
npm i -g jsx-slicerRun on a big file:
jsx-slicer --in src/BigComponent.jsx --out ./refactoredCheck the output:
The
./refactoredfolder will contain:BigComponent.jsx(rewritten with imports)components/(folder with extracted components)index.js(barrel file)
What it does
- Parses your component (Babel).
- Scans the returned JSX tree and finds:
- Duplicates: repeated subtrees (same tag/shape) → extracted into one component, reused many times.
- Singletons (optional): a very large subtree can be extracted if you pass
--allow-singletons.
- Props inference: any free identifiers used inside the block (but declared outside) become props.
- Skips risky blocks that contain React hooks.
- Writes the transformed entry file + a
/componentsfolder with generated components.
Usage
jsx-slicer --in src/LargeComponent.jsx --out ./refactor --min-size 40 --min-dupes 2 --component-prefix AutoPart --print-plan--min-size: minimum AST node count to consider for extraction.--min-dupes: min repeats for a block to be considered a "duplicate".--allow-singletons: also extract big unique chunks.--keep-locals: less-aggressive hashing (fewer merges).--jsx-root: name of the default-exported component if not obvious.--print-plan: print the extraction decisions as JSON.
Example
npm run testThis will run a dry analysis on example/Input.jsx (add your own).
Safety heuristics (why it won’t break stuff easily)
- No hooks: subtrees calling
useXxxare not extracted. - No setState capture: identifiers matching
set[A-Z]are not passed as props. - Free-identifier props: variables referenced in a block but declared outside are passed as props (read-only data or callbacks).
- Largest-first extraction: avoid overlapping replacements.
Limits & caveats
- Stateful subtrees (local
useStateetc.) are not extracted. - Context/refs/custom hooks inside subtrees prevent extraction.
- Very dynamic render branches may be skipped.
- Prop types/TS types are not synthesized (yet).
Roadmap
- Safer detection of refs/context.
- Type-driven prop maps (TS).
- CSS colocation detection.
