create-react-scaffold-cli 1.0.1 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/package.json +2 -2
  2. package/templates/base/{readme.md → README.md} +165 -95
  3. package/templates/base/docs/DOCS.md +7 -0
  4. package/templates/base/package.json +2 -0
  5. package/templates/base/src/app/App.jsx +5 -5
  6. package/templates/base/src/app/Router.jsx +34 -2
  7. package/templates/base/src/app/middlewares/AuthMiddleware.jsx +5 -0
  8. package/templates/base/src/app/middlewares/index.js +1 -0
  9. package/templates/base/src/app/providers/QueryProvider.jsx +1 -1
  10. package/templates/base/src/app/routes.registry.js +6 -0
  11. package/templates/base/src/features/sample/constants/sample.assets.js +8 -0
  12. package/templates/base/src/features/sample/constants/sample.navigations.js +5 -0
  13. package/templates/base/src/features/sample/constants/sample.queryKeys.js +3 -0
  14. package/templates/base/src/features/sample/index.js +1 -0
  15. package/templates/base/src/features/sample/pages/SamplePage.jsx +8 -0
  16. package/templates/base/src/features/sample/pages/index.js +1 -0
  17. package/templates/base/src/features/sample/sample.routes.js +13 -0
  18. package/templates/base/src/shared/{shared_readme.md → SHARED.md} +7 -1
  19. package/templates/base/src/shared/constants/app.constants.js +6 -0
  20. package/templates/base/src/shared/constants/assets.constants.js +5 -0
  21. package/templates/base/src/shared/constants/index.js +2 -0
  22. package/templates/base/src/shared/utils/localStorage.js +18 -0
  23. package/templates/base/src/shared/utils/memo.js +6 -0
  24. package/templates/base/src/shared/utils/regix.js +3 -0
  25. package/templates/base/vite.config.js +4 -5
  26. package/templates/base/src/features/sample/sample.assets.js +0 -0
  27. package/templates/base/src/features/sample/sample.navigations.js +0 -0
  28. package/templates/base/src/features/sample/sample.queryKeys.js +0 -0
  29. package/templates/base/src/features/sample/sample.routes.jsx +0 -0
  30. /package/templates/base/src/app/{app_readme.md → APP.md} +0 -0
  31. /package/templates/base/src/features/{features_readme.md → FEATURES.md} +0 -0
  32. /package/templates/base/src/{features/index.js → shared/utils/motion.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-react-scaffold-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.4",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -16,7 +16,7 @@
16
16
  "react-architecture"
17
17
  ],
18
18
  "author": "Muhammad Arsalan",
19
- "license": "ISC",
19
+ "license": "MIT",
20
20
  "description": "A CLI to scaffold a feature-first React application with clear boundaries and long-term maintainability.",
21
21
  "dependencies": {
22
22
  "commander": "^14.0.2",
@@ -1,95 +1,165 @@
1
- # React Feature‑First Scaffold
2
-
3
- ## Purpose
4
-
5
- This repository is an **internal, opinionated React scaffold** designed for large-scale frontend applications. It enforces a **feature‑first architecture**, clear ownership boundaries, and predictable patterns so teams can scale safely without architectural drift.
6
-
7
- This scaffold will later be distributed via an internal **NPM CLI** (similar to `create-react-app`) to bootstrap projects with best practices preconfigured.
8
-
9
- ---
10
-
11
- ## Core Principles
12
-
13
- - **Feature-first, not layer-first**
14
- - **Explicit boundaries** between app / features / shared
15
- - **Locality of logic** (keep things close to where they are used)
16
- - **Predictable imports** and naming conventions
17
- - **Low cognitive load** for new developers
18
-
19
- ---
20
-
21
- ## Tech Stack
22
-
23
- ### Runtime
24
-
25
- - **React 19** – UI layer
26
- - **Vite** – fast dev & build tooling
27
-
28
- ### Styling
29
-
30
- - **Tailwind CSS** – utility-first styling
31
- - **tailwind-merge** – class conflict resolution
32
- - **clsx** – conditional class composition
33
-
34
- ### Data & State
35
-
36
- - **@tanstack/react-query** – server-state management
37
- - **Axios** – HTTP client
38
-
39
- ### UI Utilities
40
-
41
- - **Radix UI** – accessible headless components
42
- - **react-hot-toast** – notifications
43
- - **react-icons** – icon system
44
-
45
- ### Code Quality
46
-
47
- - **ESLint** – linting with strict rules
48
- - **Prettier** – formatting
49
- - **Husky + lint-staged** – pre-commit enforcement
50
-
51
- ---
52
-
53
- ## High-Level Folder Structure
54
-
55
- ```txt
56
- src/
57
- app/ # Application bootstrap & global wiring
58
- features/ # Business features (isolated, self-contained)
59
- shared/ # Cross-feature reusable modules
60
- ```
61
-
62
- Each top-level folder has **its own README** explaining rules and responsibilities.
63
-
64
- ---
65
-
66
- ## Installation (WIP)
67
-
68
- > CLI installation instructions.
69
-
70
- ```bash
71
- npx create-react-scaffold-cli
72
-
73
- ```
74
-
75
- ---
76
-
77
- ## Documentation Index
78
-
79
- - `src/app/README.md` – Application bootstrap & providers
80
- - `src/features/README.md` – Feature architecture rules
81
- - `src/shared/README.md` – Shared modules & reuse policy
82
-
83
- ---
84
-
85
- ## Philosophy
86
-
87
- > **Architecture is a product feature.**
88
-
89
- This scaffold exists to reduce decision fatigue, prevent architectural erosion, and help teams move faster with confidence.
90
-
91
- ---
92
-
93
- ## Ownership
94
-
95
- This scaffold is maintained internally and should be treated as a **living standard**. Changes must be intentional, documented, and agreed upon by the frontend team.
1
+ # React Feature‑First Scaffold
2
+
3
+ ## Purpose
4
+
5
+ This repository is an **opinionated React scaffold** designed for large-scale frontend applications. It enforces a **feature‑first architecture**, clear ownership boundaries, and predictable patterns so teams can scale safely without architectural drift.
6
+
7
+ This scaffold will later be distributed via an internal **NPM CLI** (similar to `create-react-app`) to bootstrap projects with best practices preconfigured.
8
+
9
+ ---
10
+
11
+ ## Core Principles
12
+
13
+ - **Feature-first, not layer-first**
14
+ - **Explicit boundaries** between app / features / shared
15
+ - **Locality of logic** (keep things close to where they are used)
16
+ - **Predictable imports** and naming conventions
17
+ - **Low cognitive load** for new developers
18
+
19
+ ---
20
+
21
+ ## Tech Stack
22
+
23
+ ### Runtime
24
+
25
+ - **React 19** – UI layer
26
+ - **Vite** – fast dev & build tooling
27
+
28
+ ### Styling
29
+
30
+ - **Tailwind CSS** – utility-first styling
31
+ - **tailwind-merge** – class conflict resolution
32
+ - **clsx** – conditional class composition
33
+
34
+ ### Data & State
35
+
36
+ - **@tanstack/react-query** – server-state management
37
+ - **Axios** – HTTP client
38
+
39
+ ### UI Utilities
40
+
41
+ - **Radix UI** – accessible headless components
42
+ - **react-hot-toast** – notifications
43
+ - **react-icons** – icon system
44
+
45
+ ### Code Quality
46
+
47
+ - **ESLint** – linting with strict rules
48
+ - **Prettier** – formatting
49
+ - **Husky + lint-staged** – pre-commit enforcement
50
+
51
+ ---
52
+
53
+ ## High-Level Folder Structure
54
+
55
+ ```txt
56
+ src/
57
+ app/ # Application bootstrap & global wiring
58
+ features/ # Business features (isolated, self-contained)
59
+ shared/ # Cross-feature reusable modules
60
+ ```
61
+
62
+ Each top-level folder has **its own README** explaining rules and responsibilities.
63
+
64
+ ---
65
+
66
+ ## Installation
67
+
68
+ > CLI installation instructions.
69
+
70
+ ```bash
71
+ npx create-react-scaffold-cli
72
+
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Documentation Index
78
+
79
+ - `src/app/README.md` – Application bootstrap & providers
80
+ - `src/features/README.md` – Feature architecture rules
81
+ - `src/shared/README.md` – Shared modules & reuse policy
82
+
83
+ ---
84
+
85
+ ## Set Up
86
+
87
+ ### Install dependencies
88
+
89
+ ```bash
90
+ npm i
91
+ ```
92
+
93
+ ### Run application
94
+
95
+ ---
96
+
97
+ ```
98
+ npm run dev
99
+ ```
100
+
101
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
102
+
103
+ ### Lint application
104
+
105
+ ```
106
+ npm run lint
107
+ ```
108
+
109
+ ### Prettify code
110
+
111
+ ```
112
+ npm run prettier
113
+ ```
114
+
115
+ ### Build application
116
+
117
+ ```
118
+ npm run build
119
+ ```
120
+
121
+ ### Preview application
122
+
123
+ ```
124
+ npm run preview
125
+ ```
126
+
127
+ Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
128
+
129
+ # Learning Resources
130
+
131
+ ## Tailwind CSS
132
+
133
+ To learn more about `Tailwind CSS`, take a look at the following resources:
134
+
135
+ - [Tailwind ](https://tailwindcss.com) - Tailwind documentation and related resources.
136
+
137
+ ## Framer Motion
138
+
139
+ To learn more about `Framer Motion`, take a look at the following resources:
140
+
141
+ - [Framer Motion](https://www.framer.com/motion) - Framer Motion documentation and related resources.
142
+
143
+ ## React Query
144
+
145
+ To learn more about `TanStack Query`, take a look at the following resources:
146
+
147
+ - [TanStack Query](https://tanstack.com/query/latest) - React Query documentation and related resources.
148
+
149
+ ## Nuqs
150
+
151
+ To learn more about `Nuqs`, take a look at the following resources:
152
+
153
+ - [Nuqs](https://nuqs.dev/) - React Query documentation and related resources.
154
+
155
+ ## Philosophy
156
+
157
+ > **Architecture is a product feature.**
158
+
159
+ This scaffold exists to reduce decision fatigue, prevent architectural erosion, and help teams move faster with confidence.
160
+
161
+ ---
162
+
163
+ ## Ownership
164
+
165
+ This scaffold is maintained internally and should be treated as a **living standard**. Changes must be intentional, documented, and agreed upon by the frontend team.
@@ -0,0 +1,7 @@
1
+ # Scaffold Guides
2
+
3
+ ## Codebase Modules (source of truth)
4
+
5
+ - [app](../src/app/app.readme.md)
6
+ - [shared](../src/shared/shared.readme.md)
7
+ - [features](../src/features/features.readme.md)
@@ -32,12 +32,14 @@
32
32
  "@tanstack/react-query-devtools": "^5.91.2",
33
33
  "axios": "^1.13.2",
34
34
  "clsx": "^2.1.1",
35
+ "framer-motion": "^12.26.2",
35
36
  "nuqs": "^2.8.6",
36
37
  "postcss": "^8.5.6",
37
38
  "react": "^19.2.0",
38
39
  "react-dom": "^19.2.0",
39
40
  "react-hot-toast": "^2.6.0",
40
41
  "react-icons": "^5.5.0",
42
+ "react-router-dom": "^7.12.0",
41
43
  "tailwind-merge": "^3.4.0",
42
44
  "tailwindcss": "^4.1.18"
43
45
  },
@@ -1,13 +1,13 @@
1
1
  import { Toaster } from '@/shared/ui';
2
2
  import { QueryProvider } from './providers';
3
+ import { Router } from './Router';
4
+ import { memo } from '@/shared/utils';
3
5
 
4
- function App({ children }) {
6
+ export const App = memo(() => {
5
7
  return (
6
8
  <QueryProvider>
7
- {children}
9
+ <Router />
8
10
  <Toaster />
9
11
  </QueryProvider>
10
12
  );
11
- }
12
-
13
- export default App;
13
+ });
@@ -1,4 +1,36 @@
1
+ import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
2
+ import { featureRoutes } from './routes.registry';
3
+ import { AuthMiddleware } from './middlewares';
4
+ import { Layouts } from '@/shared/constants';
5
+ import { memo } from '@/shared/utils';
1
6
 
2
- export const Router = () => {
3
- return <div className="">{authRoute}</div>;
7
+ const layoutMap = {
8
+ dashboard: null,
9
+ none: ({ children }) => children,
4
10
  };
11
+
12
+ export const Router = memo(() => {
13
+ return (
14
+ <BrowserRouter>
15
+ <Routes>
16
+ {featureRoutes.map((route, index) => {
17
+ const Layout = layoutMap[route.layout ?? Layouts.None];
18
+
19
+ let element = <Layout>{route.element}</Layout>;
20
+
21
+ if (route.protected) {
22
+ element = (
23
+ <AuthMiddleware>
24
+ <Layout>{route.element}</Layout>
25
+ </AuthMiddleware>
26
+ );
27
+ }
28
+
29
+ return <Route key={index} path={route.path} element={element} />;
30
+ })}
31
+
32
+ <Route path="/*" element={<Navigate to="/login" replace />} />
33
+ </Routes>
34
+ </BrowserRouter>
35
+ );
36
+ });
@@ -0,0 +1,5 @@
1
+ import { memo } from '@/shared/utils';
2
+
3
+ export const AuthMiddleware = memo(({ children }) => {
4
+ return children;
5
+ });
@@ -0,0 +1 @@
1
+ export { AuthMiddleware } from './AuthMiddleware';
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
3
2
  import { AxiosError } from 'axios';
4
3
  import toast from 'react-hot-toast';
5
4
  import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
5
+ import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
6
6
 
7
7
  export const QueryProvider = ({ children }) => {
8
8
  const [queryCache] = React.useState(
@@ -0,0 +1,6 @@
1
+ import { sampleRoutes } from '@/features/sample';
2
+
3
+ export const featureRoutes = [
4
+ ...sampleRoutes,
5
+ // ...anotherFeatureRoutes
6
+ ];
@@ -0,0 +1,8 @@
1
+ export const SampleAssets = {
2
+ Images: {
3
+ Sample: './assets/images/',
4
+ },
5
+ Icons: {
6
+ Sample: './assets/icons/',
7
+ },
8
+ };
@@ -0,0 +1,5 @@
1
+ export const SampleNavigation = {
2
+ Sample: '/sample',
3
+ };
4
+
5
+ export const SampleSearchParamsKey = {};
@@ -0,0 +1,3 @@
1
+ export const sampleQueryKey = {
2
+ all: ['sample'],
3
+ };
@@ -0,0 +1 @@
1
+ export { sampleRoutes } from './sample.routes';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { memo } from '@/shared/utils';
3
+
4
+ const SamplePage = memo(() => {
5
+ return <div>SamplePage</div>;
6
+ });
7
+
8
+ export default SamplePage;
@@ -0,0 +1 @@
1
+ export const SamplePage = React.lazy(() => import('./SamplePage'));
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { Layouts } from '@/shared/constants';
3
+ import { SampleNavigation } from './constants/sample.navigations';
4
+ import { SamplePage } from './pages';
5
+
6
+ export const sampleRoutes = [
7
+ {
8
+ path: SampleNavigation.Sample,
9
+ element: <SamplePage />,
10
+ protected: true,
11
+ layout: Layouts.None,
12
+ },
13
+ ];
@@ -1,6 +1,7 @@
1
1
  # Shared Module
2
2
 
3
3
  ## Purpose
4
+
4
5
  The `shared` folder contains **cross-feature reusable code**.
5
6
 
6
7
  It exists to prevent duplication — not to become a dumping ground.
@@ -12,6 +13,7 @@ It exists to prevent duplication — not to become a dumping ground.
12
13
  ## What Belongs in Shared
13
14
 
14
15
  Only code that is:
16
+
15
17
  - Used by **multiple features**
16
18
  - **Stateless or generic**
17
19
  - Independent of business rules
@@ -38,12 +40,14 @@ shared/
38
40
  ## Rules
39
41
 
40
42
  ### ✅ Allowed
43
+
41
44
  - UI primitives (Button, Modal)
42
45
  - Generic hooks (useDebounce)
43
46
  - Axios/query setup
44
47
  - Theme tokens
45
48
 
46
49
  ### ❌ Not Allowed
50
+
47
51
  - Feature logic
48
52
  - Business rules
49
53
  - Feature-specific constants
@@ -67,11 +71,13 @@ import { authQueryKeys } from '@/features/auth';
67
71
  ## Constants Policy
68
72
 
69
73
  Shared constants should be:
74
+
70
75
  - Truly global
71
76
  - Stable
72
77
  - Rarely changed
73
78
 
74
79
  Examples:
80
+
75
81
  - Pagination defaults
76
82
  - Environment keys
77
83
  - Generic route params
@@ -83,6 +89,7 @@ Examples:
83
89
  Global contexts should be rare.
84
90
 
85
91
  Before adding one, ask:
92
+
86
93
  1. Is this needed by multiple unrelated features?
87
94
  2. Can this live inside a feature instead?
88
95
 
@@ -95,4 +102,3 @@ If unsure — **do not add it here**.
95
102
  Shared code is a **dependency magnet**.
96
103
 
97
104
  The smaller it stays, the healthier the system remains.
98
-
@@ -1,3 +1,9 @@
1
1
  export const ENV = {
2
2
  BACKEND_URL: import.meta.env.VITE_BACKEND_URL,
3
3
  };
4
+
5
+ export const Layouts = {
6
+ Dashboard: 'dashboard',
7
+ Auth: 'auth',
8
+ None: 'none',
9
+ };
@@ -0,0 +1,5 @@
1
+ export const AppAssets = {
2
+ Logos: {},
3
+ Images: {},
4
+ Icons: {},
5
+ };
@@ -0,0 +1,2 @@
1
+ export * from './app.constants';
2
+ export { AppAssets } from './assets.constants';
@@ -0,0 +1,18 @@
1
+ export const LocalStorageGetItem = (key) => {
2
+ if (typeof window !== 'undefined') {
3
+ return localStorage.getItem(key);
4
+ }
5
+ return null;
6
+ };
7
+
8
+ export const LocalStorageSetItem = (key, value) => {
9
+ if (typeof window !== 'undefined') {
10
+ localStorage.setItem(key, value);
11
+ }
12
+ };
13
+
14
+ export const LocalStorageRemoveItem = (key) => {
15
+ if (typeof window !== 'undefined') {
16
+ localStorage.removeItem(key);
17
+ }
18
+ };
@@ -1,3 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
+ /**
4
+ * @template T
5
+ * @param {React.ComponentType<T>} Component
6
+ * @returns {React.MemoExoticComponent<React.FC<T>>}
7
+ */
8
+
3
9
  export const memo = (Component) => React.memo(Component);
@@ -0,0 +1,3 @@
1
+ export const normalizeRegex = (string) => {
2
+ return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3
+ };
@@ -1,13 +1,12 @@
1
- import { defineConfig } from "vite";
2
- import react from "@vitejs/plugin-react";
3
- import path from "path";
1
+ import { defineConfig } from 'vite';
2
+ import react from '@vitejs/plugin-react';
3
+ import path from 'path';
4
4
 
5
- // https://vite.dev/config/
6
5
  export default defineConfig({
7
6
  plugins: [react()],
8
7
  resolve: {
9
8
  alias: {
10
- "@": path.resolve(import.meta.dirname, "./src"),
9
+ '@': path.resolve(import.meta.dirname, './src'),
11
10
  },
12
11
  },
13
12
  preview: {