create-modux-erp
v1.0.0
Published
Scaffold React 19 + TypeScript ERP front-ends with a strict feature-module architecture.
Maintainers
Readme
create-modux-erp
Scaffold React 19 + TypeScript ERP front-ends with a strict, predictable feature-module architecture. Ships two binaries from one package: create-modux-erp (project scaffold) and modux (feature/CRUD generators).
Requirements
- Node ≥ 20
- npm (the scaffolder shells out to
npm install)
Quick start
# 1. Scaffold a new project (installs all deps at their latest versions)
npx create-modux-erp my-erp
cd my-erp
npm run dev # http://localhost:5173
# 2. Generate a feature module (auto-registers its route + menu entry)
npx modux gen module orders
# 3. Add CRUD entities to a module (service + hook quartet + pages)
npx modux gen crud orders invoice
npx modux gen crud orders customermodux is added to the project as a dev-dependency during scaffold, so npx modux … resolves the local binary. (Developing the generator itself? npm link it instead.)
Flags
create-modux-erp <app> --no-install— scaffold only, skip dependency installation.
Tech stack
React 19 · Vite (@vitejs/plugin-react-swc) · Ant Design 5 · Tailwind CSS 4 (@tailwindcss/vite) · TanStack React Query (server state) · Redux Toolkit + react-redux (client state) · React Router 7 data router · Axios · Formik + Yup · i18next / react-i18next (uz, ru) · dayjs (uz + isoWeek) · chart.js + react-chartjs-2 · lucide-react · motion · react-hot-toast.
Versions are not pinned in templates —
create-modux-erprunsnpm installso npm resolves thelatestdist-tag and writes the resolved caret range at generation time.
Architecture & conventions
- Path alias
@/* → src/*everywhere (tsconfig+ Vite). - Server state lives in React Query; client state in Redux Toolkit. Never call Axios from a component.
- Data flow:
page → hook → service → endpoints. Endpoints and query keys are centralized per module underconstants/. - Hooks are one-per-file:
useGetList,useGetDetail,useCreate,useUpdateper entity. - Pages are always
pages/<entity>/index.tsx(+add.tsx,view.tsx). - A generated module's default entity equals the module name and lives at the module route root;
gen crudadds further entities as nested route groups.
Runtime wiring
$axiosPrivate→baseURL = VITE_API_BASE_URL_PATH + "/api",timeout: 50000. Request interceptor injectsAuthorization: Bearer <localStorage.login.token>andX-Organization-Id(fromlocalStorage.orgorlogin.user.organizationId). On401:dispatch(logout())then redirect to/login.rootReducerclearslocalStorage(login,org) and resets the store onlogout.i18ninitializes with uz (default) + ru;dayjssets the uz locale and the isoWeek plugin at startup.
Generators are idempotent
Re-running gen module / gen crud warns and skips existing files and never duplicates a registration — route/menu/endpoint/queryKey/type injection is keyed on marker comments (/* modux:* */) with de-dupe guards.
Configuration
Copy .env.example → .env and set:
VITE_API_BASE_URL_PATH=https://your-api.example.comThe app runs without it (calls fall back to a relative /api).
Deployment
vercel.json ships an SPA rewrite (/(.*) → /). Build with npm run build (tsc -b && vite build); output is dist/.
Notes on the generated skeleton
A few spec folders are documented extension points and are not pre-filled with empty files: components/ui/{card,text,table,filters}, components/widget/{excelimport,modals}, assets/{images,lotties}. Duplicate paths in the original spec were consolidated to a single canonical home (app/layouts for route layouts, components/{navbar,sidebar} for chrome, shared/{hooks,types} for cross-cutting code).
License
MIT
