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.
- package/package.json +2 -2
- package/templates/base/{readme.md → README.md} +165 -95
- package/templates/base/docs/DOCS.md +7 -0
- package/templates/base/package.json +2 -0
- package/templates/base/src/app/App.jsx +5 -5
- package/templates/base/src/app/Router.jsx +34 -2
- package/templates/base/src/app/middlewares/AuthMiddleware.jsx +5 -0
- package/templates/base/src/app/middlewares/index.js +1 -0
- package/templates/base/src/app/providers/QueryProvider.jsx +1 -1
- package/templates/base/src/app/routes.registry.js +6 -0
- package/templates/base/src/features/sample/constants/sample.assets.js +8 -0
- package/templates/base/src/features/sample/constants/sample.navigations.js +5 -0
- package/templates/base/src/features/sample/constants/sample.queryKeys.js +3 -0
- package/templates/base/src/features/sample/index.js +1 -0
- package/templates/base/src/features/sample/pages/SamplePage.jsx +8 -0
- package/templates/base/src/features/sample/pages/index.js +1 -0
- package/templates/base/src/features/sample/sample.routes.js +13 -0
- package/templates/base/src/shared/{shared_readme.md → SHARED.md} +7 -1
- package/templates/base/src/shared/constants/app.constants.js +6 -0
- package/templates/base/src/shared/constants/assets.constants.js +5 -0
- package/templates/base/src/shared/constants/index.js +2 -0
- package/templates/base/src/shared/utils/localStorage.js +18 -0
- package/templates/base/src/shared/utils/memo.js +6 -0
- package/templates/base/src/shared/utils/regix.js +3 -0
- package/templates/base/vite.config.js +4 -5
- package/templates/base/src/features/sample/sample.assets.js +0 -0
- package/templates/base/src/features/sample/sample.navigations.js +0 -0
- package/templates/base/src/features/sample/sample.queryKeys.js +0 -0
- package/templates/base/src/features/sample/sample.routes.jsx +0 -0
- /package/templates/base/src/app/{app_readme.md → APP.md} +0 -0
- /package/templates/base/src/features/{features_readme.md → FEATURES.md} +0 -0
- /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.
|
|
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": "
|
|
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 **
|
|
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
|
-
##
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
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.
|
|
@@ -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
|
-
|
|
6
|
+
export const App = memo(() => {
|
|
5
7
|
return (
|
|
6
8
|
<QueryProvider>
|
|
7
|
-
|
|
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
|
-
|
|
3
|
-
|
|
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 @@
|
|
|
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 @@
|
|
|
1
|
+
export { sampleRoutes } from './sample.routes';
|
|
@@ -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
|
-
|
|
@@ -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,13 +1,12 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
2
|
-
import react from
|
|
3
|
-
import path from
|
|
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
|
-
|
|
9
|
+
'@': path.resolve(import.meta.dirname, './src'),
|
|
11
10
|
},
|
|
12
11
|
},
|
|
13
12
|
preview: {
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|