Dependency modernization pass. Every dependency is at its latest version, all npm audit vulnerabilities are gone (now 0, was 5), and sixteen abandoned or unused packages were removed — the still-used ones replaced by maintained libraries or small local components so no demo loses functionality. Verified green through lint (0 errors), 23 unit tests, the production build, and the 24-route Playwright smoke test (plus a 10-route smoke pass over every swapped page).
- 0
npm auditvulnerabilities (was 5: 2 high, 3 moderate). Theuuidadvisory came in through the unusedreact-validation; removing it plus a non-breakingnpm audit fix(transitivebrace-expansion,fast-uri,tmp) cleared the rest.
react-data-table-component7 → 8 — the only dependency a major version behind. No call-site changes needed.- All other ranges already tracked latest; the lockfile was refreshed.
react-validation,react-form-validator-core,react-table,react-image-crop,react-on-screen,react-animations,aphrodite, plus the now-unusedsweetalert(v2) and the briefly-added@smastrom/react-rating.
react-input-mask(2022) →@react-input/maskreact-color(2022) →@uiw/react-colorreact-bootstrap-sweetalert(2022) →sweetalert2react-numeric-input(2022) →rc-input-number(samerc-*family as the existing slider/tooltip)react-cropper(2023) →react-easy-cropreactourv1 (2024) →@reactour/tourv3 (hook-basedTourProvider/useTour)ckeditor4/ckeditor4-react(end-of-life software) →react-simple-wysiwygreact-rating(2022) → localsrc/components/Rating.jsx(keeps the per-position custom-symbol API the demo relies on)react-sparklines(2022) → localsrc/components/Sparklines/(faithful reimplementation of the same component API and point math)react-responsive-tabs(2022) → localsrc/components/ResponsiveTabs/(emits the sameRRT__*class structure the SCSS targets)react-sticky-el(2024) → localsrc/components/Sticky.jsx(native CSSposition: sticky)react-liquid-gauge(2022) → localsrc/components/LiquidGauge.jsx(animated SVG wave fill; also drops the undeclaredd3-interpolateimport)moment(maintenance-mode) →date-fns(already a dependency):dateFnsLocalizerfor the big-calendar demo,isAfterfor the date-range pickers
react-simple-maps(v3, 2023) — still on its latest major and not abandoned; reimplementing its d3-geo projection/zoom stack as custom code would add risk with no security or maintenance benefit.
vite.config.js: trimmed the CJS-interop list to the five packages that still need it, removed the deadvendor-ckeditormanualChunk, and droppedreact-table/reactour/react-responsive-tabs/ckeditor4-reactfromoverrides.
Phase 14–17. The "exceptional" polish pass: real dark mode, accessibility basics, four more unmaintained dependencies gone, and a clear path for consumers to turn the template into their own project. Eight commits since 4.4.0, every one independently green through lint + unit + build + Playwright.
- Real dark mode. New
darkModefield on theThemeOptionsslice ('auto' | 'light' | 'dark'), persisted tolocalStoragealongside the other theme prefs.src/hooks/useDarkModeSync.jswrites the resolved value to<html data-bs-theme>so Bootstrap 5.3's native dark palette kicks in across reactstrap, cards, forms, tables, and everything else styled with Bootstrap utilities.'auto'followsprefers-color-schemeand reacts live to OS changes; explicit choices override it. Three-button Auto/Light/Dark control at the top of the ThemeOptions side panel, wired witharia-pressedfor AT. - Accessibility primitives. Top-level
<a class="skip-link" href="#main-content">jumps keyboard users past the sidebar/header.<header role="banner">,<div role="navigation" id="app-sidebar" aria-label="Primary">, and<main id="main-content" tabIndex={-1}>landmarks so screen readers announce the shell correctly.:focus-visiblefallback ring for every keyboard-interactive element the template's custom classes wouldn't otherwise highlight. - ARIA on icon-only buttons. Layout-configurator cog, mobile hamburger, and mobile-overflow button all get
aria-label,aria-expanded/aria-pressed,aria-controlswhere they reference other landmarks, and propertype="button"attributes. The mobile overlay scrim gets keyboard activation (Enter/Space/Escape). src/hooks/useInView.js— a ~25-lineIntersectionObserverhook replacing thereact-visibility-sensorrender-prop pattern.src/components/Loader.jsx— a local<Loader>+Typesdictionary matching the oldreact-loadersAPI, wired to the existingloaders.cssanimations.src/DemoPages/routes.jsx— demo routes are now defined in the demo folder instead ofLayout/AppMain, soLayout/is framework-only.STARTER.md— step-by-step guide for stripping the template down to a starter: what to keep, what to delete, the three edits you need afterrm -rf src/DemoPages, and how the reliability features (ErrorBoundary, persistence, dark mode, a11y) survive the trim automatically.
- Layout primitives are now semantic.
Layout/AppHeaderrenders as a<header>,Layout/AppSidebaras a<nav>-equivalentdiv role="navigation",DemoPages/Main's page-content slot as<main>. Same visual layout, usable tree for assistive tech. - Dashboard sparkline widgets span the full card width in CRM Dashboard 2 and Analytics (eight
<Col md="9">→md="12"). The previous columns left ~25% of each card empty on the right. persistThemeOptionswhitelist extended to includedarkMode. Existing stored state upgrades cleanly — the load path merges persisted keys over the reducer defaults so first-time visits to 4.5.0 get'auto'.
react-anime(peer-pinned to 17.x, zero source imports). Dropped fromdependenciesand from the nested override block. Also prunedreact-anime|animejsfrom thevendor-motionmanualChunks rule.react-visibility-sensor(unmaintained since 2020). Replaced byuseInView+ a rewrittenDemoPages/Elements/ScreenVisibility/Examples/Fade.jsxthat uses it.react-loaders(last published 2018). Replaced by the local<Loader>component viaresolve.alias; the five consumer files still import from'react-loaders'for zero source-level churn.- Three entries from the Phase 7 CJS interop list (
react-loaders,react-visibility-sensor, and indirectly the vendor-motion chunk entries) — they're not CJS packages anymore, they're local modules.
- New test files:
src/hooks/useDarkModeSync.test.jsx(5 tests), extendedsrc/reducers/ThemeOptions.test.jsxwith adarkModecase. Total unit suite: 23 tests across 6 files (was 16/5). vitest.setup.jsalready handles thematchMediamock used by the new hook's tests.- CI workflow, Playwright suite, and all other scaffolding from 4.3.0 / 4.4.0 carry over unchanged.
Pure forward compatibility. Users who already had ThemeOptions prefs in localStorage get 'auto' for darkMode on first load (defaults merge over persisted state). Nothing else changes on disk.
If you were using react-anime, react-visibility-sensor, or react-loaders directly in your fork: the first two are gone; the third is aliased to the local src/components/Loader.jsx which preserves the <Loader> + Types surface. Custom loader types or deep configuration of the old packages won't carry over — the local component only does what loaders.css can do (which is every animation the template actually uses).
The "every page actually works" release. Phases 7–12 fix seven distinct runtime bugs latent on the Vite migration since v4.2.0, halve the largest JS chunk, add persistence and crash recovery, and wire in a route smoke test that prevents a repeat.
- Top-level
<ErrorBoundary>at the app root. A crash in any demo page now renders a friendly card (title, error message, component stack in dev, reload button) instead of blanking the app. Covers the exact class of failure this branch was masking — invalid React elements from CJS-interop mismatches. - Theme preferences persist across reloads.
src/config/persistThemeOptions.jswhitelists 15ThemeOptionsfields (color scheme, fixed header/sidebar/footer toggles, background image + opacity, page-title toggles, …) and hydrates them fromlocalStorageon startup. Writes dedupe on-change so non-persisted slice updates don't touch storage; quota / disabled / private-mode exceptions are swallowed silently. - Playwright route smoke test (
e2e/routes.spec.js). Spins upnpm run preview, walks 24 curated demo routes against the production build, fails on any uncaught page error, "Element type is invalid" / "not a constructor" / "ChunkLoadError" console error, or missing page copy. Wired into CI afterbuild; failing runs upload the Playwright report as an artifact. Scripts:npm run test:e2e,npm run test:e2e:install. jsconfig.json+ JSDoc types on the Redux store factory, the theme-persistence helpers, andErrorBoundary. Editors get autocomplete + go-to-definition on the hand-off points where type errors cascade the furthest, without the cost of a full TypeScript migration (checkJs: false).- CJS-import interop plugin (
cjsInteropPlugininvite.config.js). Rewrites consumer-sideimport X from 'pkg'/import { Y } from 'pkg'for 13 Babel-compiled CJS packages into a namespace-destructure that handles bothmodule.exports = Xand__esModule + exports.default = Xshapes. Fixes the "got object" / "got undefined" element-type errors on CRM Dashboard 2, Cards Advanced, and the Suspense fallback. - Route-level bundle test coverage. Every dashboard, app, component demo, forms, tables, charts, user page, and widget entry point now has at least one automated render check. 24 tests total, ~17s wall clock in CI.
- Bundle size:
vendor-fontawesome668 kB → 94 kB (gzip 259 kB → 29.5 kB). The FontAwesome demo page imported the wholefabbrand set (~500 icons) to show two; switched to named imports forfaFontAwesomeandfaInternetExplorer. ~86% off the chunk on disk, ~89% off the wire. Biggest initial-load win available in the template right now. internmappinned to^2.0.3+ aliased to its UMD dist. Rolldown wraps the ESMexport class InternMapin a lazy__esmMin(cb)initializer, butd3-array/ordinal.jscallsnew InternMap()eagerly inside another wrapper — the lazycbnever fires before use, so every production-build dashboard using recharts scales threwTypeError: InternMap is not a constructor. The UMD dist defines the class synchronously.react-ispinned to^19.2.5viaoverrides. Hoistedreact-is@16.13.1copies (insideprop-types,hoist-non-react-statics,reactour) use the pre-React-19Symbol.for('react.element')and rendered elements React 19 rejected as "older". Dedupes the tree to 19.2.5.- Relocated linearicons fonts to
public/fonts/linearicons/. SCSS now references them as absolute URLs (/fonts/linearicons/...) so they resolve identically in dev and the production build — Vite doesn't rebase CSS URLs that come from@import-ed SCSS partials, which silently broke everylnr-*glyph. - HTTPS-only demo links in the Leaflet maps demo (SRTM, Stamen) and the Guided Tours demo (CodePen).
- CRM Dashboard 2 renders (was "Element type is invalid: got object" —
react-data-table-componentdefault-import namespace leak, via the Phase 7 interop plugin). - Cards Advanced renders (same class of bug via
react-responsive-tabs). - Every
<Suspense fallback>renders (same class viareact-loaders' named import). - Sales / Analytics / CRM / Commerce dashboards render (combined internmap + react-is + react-sweet-progress fixes).
lnr-*icons on /elements/navigation (linearicons font path).
react-sweet-progress@1.1.2dependency. The old@babel/preset-reactoutput inlinedSymbol.for('react.element')directly into itscreateElementhelper; every<Progress>it produced arrived at React 19 with the pre-19$$typeof. Replaced by a local drop-in atsrc/components/CircleProgress.jsxthat matches the public API (<Progress type="circle|line" percent theme={{ active: { color, trailColor } }} />). The previously neededresolve.aliashop is gone too.
- CI workflow (
.github/workflows/ci.yml) extended withnpx playwright install --with-deps chromiumand the route smoke test step. Playwright report uploads on failure with 7-day retention. .gitignoreadditions for/test-results,/playwright-report,/playwright/.cache.
No code changes in consumer projects. If you're deploying:
- Pull latest, delete
node_modulesandpackage-lock.json. npm install --legacy-peer-deps(still needed for the React 19 / older lib peer ranges).- Run
npm run test:e2e:installonce to fetch the Chromium browser Playwright uses. - Sanity-check with
npm run lint,npm test -- --run,npm run build,npm run test:e2e.
If you have a custom <Progress> usage, check the CircleProgress.jsx API — it covers the 95% case (type, percent, theme.active.color, theme.active.trailColor) but deliberately doesn't reimplement every edge of the original.
First release focused purely on developer experience around the template — no user-facing UI changes. If you're upgrading from 4.2.0: delete node_modules and package-lock.json, then npm install --legacy-peer-deps; npm install now finishes in ~1 minute instead of stalling.
- Vitest + React Testing Library test harness.
vitest.config.js(jsdom env,srcalias, coverage exclusions for assets/polyfills/serviceWorker) andvitest.setup.js(@testing-library/jest-dommatchers, RTL cleanup,matchMedia/ResizeObservershims). Scripts:npm test(watch),npm test -- --run(single),npm run test:ui,npm run test:coverage(v8). Initial tests cover theThemeOptionsreducer,configureAppStore, and<AppFooter />. - GitHub Actions CI workflow (
.github/workflows/ci.yml) runsnpm ci --legacy-peer-deps,npm run lint,npx vitest run, andnpm run buildon every push tomaster/main/feature/**and on every PR. Node version comes from.nvmrc; concurrency cancels stale runs on the same ref. - CONTRIBUTING.md covering prerequisites, scripts, env vars, project layout, code style, testing, commits, and PR expectations.
.env.exampledocumentingVITE_PORTandVITE_BASE.- Env-driven dev server and public base path.
vite.config.jsnow readsVITE_PORTandVITE_BASEvia Vite'sloadEnv, so deploys behind a subdirectory (or on a different dev port) no longer require editing the config.
- Pruned the
overridesblock. Dropped 11 of 18 nested React 19 overrides whose upstream packages already declare React 19 in their peer deps (rc-slider,rc-tooltip,rc-util,rc-motion,@rc-component/trigger,@rc-component/portal,rc-resize-observer,react-copy-to-clipboard,styled-components,react-resize-detector,react-intersection-observer). The 7 still pinned (ckeditor4-react,react-anime,react-popper,react-responsive-tabs,react-simple-maps,react-table,reactour) genuinely cap their React peer at ≤18 and still need the override. Net effect: npm's dependency resolver no longer hangs —npm install --legacy-peer-depsnow finishes in ~1 minute on a clean tree. - HTTPS-only demo links. Switched remaining
http://URLs in the Leaflet map demo (SRTM, Stamen) and the Guided Tours demo (CodePen) tohttps://. The SVG XML namespace URI (http://www.w3.org/2000/svg) is intentionally left as HTTP — it's a spec-mandated identifier, not a fetchable URL. jsx-a11y/label-has-associated-controldowngraded from error to warning ineslint.config.jsso the demo forms (which intentionally render labels without associated inputs) don't fail CI's lint step. Awareness preserved as a warning, consistent with the project's existing jsx-a11y stance.
- Stale / renamed
node_modules*directories no longer pollute lint and git scans..gitignoreandeslint.config.jsnow both ignore.node_modules*andnode_modules_*patterns, so local debris from package-manager experiments (e.g. a renamed.node_modules_obsolete) can't silently wedgenpm run lintorgit status.
- Migrated from Create React App to Vite: Complete build system migration from CRA to Vite 7.2.6 for significantly faster development server startup and hot module replacement (HMR). Build times reduced from ~30s to ~3s.
- Renamed all .js files to .jsx: Converted 348 JavaScript files to use the .jsx extension for better tooling support and Vite compatibility.
- Replaced Google Maps with Leaflet/OpenStreetMap: Removed dependency on Google Maps API key. Interactive maps now use free OpenStreetMap tiles via react-leaflet with multiple map styles (Standard, Dark, Satellite, Topographic, Watercolor).
- Enhanced Vector Maps: Completely redesigned vector maps with proper sizing, interactive hover effects, zoom/pan functionality, and city markers with tooltips showing population data.
- Vite Configuration: New
vite.config.jswith Node.js polyfills, React plugin, and optimized settings. - Custom LoadingOverlay Component: Created React 19 compatible loading overlay component using Framer Motion to replace deprecated
react-loading-overlay-ts. - Custom TabsWrapper Component: Created
src/utils/TabsWrapper.jsxto replace rc-tabs with a React 19 compatible implementation. - Custom TransitionWrapper Component: Created
src/utils/TransitionWrapper.jsxto replace react-transition-group with Framer Motion.
- React 19 Compatibility: Resolved "A React Element from an older version of React was rendered" errors by adding comprehensive npm overrides for packages with pre-bundled older React versions.
- SCSS Import Paths: Removed tilde (~) prefix from all SCSS imports for Vite compatibility.
- Create React App: Removed react-scripts, react-app-rewired, and config-overrides.js.
- Deprecated Packages: Removed
react-loading-overlay-ts,google-map-react,rc-tabs,react-transition-group.
- 0 Vulnerabilities: Clean security audit with all dependencies updated.
- Upgraded to React 19.2.0: Updated from React 19.1.0 to the latest React 19.2.0 release.
- Comprehensive Dependency Update: Updated all 100+ dependencies to their latest versions, including major version upgrades:
@fortawesome/*packages: 6.7.2 → 7.1.0@fortawesome/react-fontawesome: 0.2.2 → 3.1.1apexcharts: 4.7.0 → 5.3.6recharts: 2.13.3 → 3.5.1framer-motion: 12.19.1 → 12.23.25react-router-dom: 7.6.2 → 7.9.6typescript: 5.7.2 → 5.9.3bootstrap: 5.3.7 → 5.3.8- And many more minor/patch updates
- Dependency Cleanup: Removed 22 unused dependencies, reducing total packages from 1,908 to 1,807 (~100 packages removed including transitive dependencies).
- Testing Libraries: Removed
@testing-library/jest-dom,@testing-library/react,@testing-library/user-event(no test files in project) - Unused UI Components: Removed
chartist,jquery,rc-tree,react-compound-slider,react-dnd,react-dnd-html5-backend,react-map-gl,react-outside-click-handler,react-scroll,react-sizeme,react-syntax-highlighter - Unused Redux Packages: Removed
redux-form,redux-logger,redux-thunk(using @reduxjs/toolkit instead) - Duplicate/Unused Packages: Removed
dropzone(using react-dropzone),globalize,install,web-vitals,@types/markerclustererplus
- Replaced namor with browser-compatible solution: The
namorpackage v3 is not browser-compatible (uses Node.js fs module). Replaced with inline name generator arrays for demo data tables.
- Upgraded to React 19.1.0: Migrated the entire project to
react@^19.1.0andreact-dom@^19.1.0. - Comprehensive Dependency Update: Updated numerous packages, including
framer-motion, and resolved complex dependency conflicts. - Modernized SCSS: Replaced deprecated Sass functions (
map-merge,nth) with their modern module-based equivalents (map.merge,list.nth). - Webpack 5 Polyfills: Integrated necessary polyfills (
crypto-browserify,stream-browserify, etc.) for Node.js core modules no longer included in modern webpack. - Build Configuration: Implemented a robust
config-overrides.jsto manage webpack fallbacks and suppress excessive console warnings from third-party libraries. - Bootstrap 5 Compatibility: Updated all components and classes to be fully compatible with Bootstrap 5 (e.g.,
text-bg-*badges,me/msspacing).
- Fixed Collapsed Sidebar Alignment: Resolved persistent icon alignment issues in the collapsed sidebar for both static and hover states, ensuring pixel-perfect centering.
- Fixed User Profile Dropdown: Corrected the positioning of the user profile dropdown to prevent it from rendering off-screen on larger viewports.
- Fixed
reactstrapComponents: RefactoredFormandFormGroupcomponents to remove the deprecatedinlineprop, aligning them with React 19 and Bootstrap 5 standards. - Fixed Vector Maps Component: Resolved a critical data fetching error by replacing a dead URL with a local data source.
3.0.0 - 2023-11-20
- Migrated to React v18.
- Import SCSS files from
node_modulesby using the sass-loader instead of relative paths like../../node_modules. - Upgraded all dependencies to latest versions.
- Fixed SCSS bugs.
- Updated Libraries
- Updated to React 17
- Added react-app-rewired
- Updated to Bootstrap 5
- Updated to Reactstrap 9
- Updated all Libraries
- Updated Libraries
- Updated Libraries
- Initial Release