What problem does it solve? Adding React to a traditional Liferay OSGi module involves many moving parts — choosing between a Client Extension and a module, picking the right bundler, keeping React external so duplicate copies don't break hooks, and wiring npm output into the Gradle build. This Skill guides that entire decision and scaffolding process so the module builds and deploys correctly the first time. ## Core Features & Use Cases - Container decision guidance: Checks the workspace's Liferay version and helps decide between a traditional OSGi module and a Custom Element Client Extension before any scaffolding happens. - Two proven patterns: Covers a whole React-driven portlet via blade's npm-react-portlet template (esbuild, plain JS) and React mounted from a custom JSP/FTL tag via @liferay/npm-scripts with TypeScript, modeled on a real modules/search example. - Shared-React safety: Explains the load-bearing --external:react flags and imports mapping to @liferay/frontend-js-react-web that prevent duplicate React copies and "Invalid hook call" errors. - Use Case: A developer needs a React search component rendered inside an existing JSP tag in a DXP workspace — the Skill walks through assembling package.json, npmscripts.config.js, the TS barrel export, bnd.bnd, and the Gradle copyNpmBuild wiring, then deploying with blade gw :modules:search:deploy. ## Quick Start Ask the assistant to set up React in a Liferay module, stating whether the React app is a whole portlet or mounted inside a custom JSP/FTL tag.