create-twinbloc-app 0.1.2 → 0.1.3

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 (3) hide show
  1. package/README.md +77 -10
  2. package/bin/cli.js +26 -12
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Create Twinbloc App
2
2
 
3
- Create a React Native app from the Twinbloc starter template (Expo + Expo Router).
3
+ Create a React Native app with the Twinbloc starter template. This CLI scaffolds a production-ready Expo SDK 54 project with Expo Router, TypeScript, native modules, and a curated set of defaults for state, API, UI, and localization.
4
+
5
+ ## What You Get
6
+
7
+ - Expo SDK 54 project with Expo Router and typed routes
8
+ - React Native 0.81 + React 19 setup
9
+ - TypeScript-first structure with strict TS config
10
+ - NativeWind + Tailwind utilities, themed UI primitives, and tokens
11
+ - Zustand store examples with persisted auth state
12
+ - TanStack Query with MMKV persistence
13
+ - Axios API client with auth-aware helpers
14
+ - i18next localization with English, Spanish, French, and Arabic samples
15
+ - Reanimated-ready bottom sheet provider and gesture handler setup
16
+ - Toasts, haptics, blur, image, and icon tooling prewired
17
+ - Environment-driven app config for name, slug, scheme, bundle IDs
4
18
 
5
19
  ## Requirements
6
20
 
@@ -8,7 +22,7 @@ Create a React Native app from the Twinbloc starter template (Expo + Expo Router
8
22
  - npm, yarn, pnpm, or bun
9
23
  - Xcode for iOS (macOS) and/or Android Studio for Android
10
24
 
11
- ## Quick Start
25
+ ## Quick Start (npm)
12
26
 
13
27
  ```bash
14
28
  npx create-twinbloc-app@latest MyApp
@@ -16,6 +30,13 @@ cd MyApp
16
30
  npm run start
17
31
  ```
18
32
 
33
+ Then build and open a dev client:
34
+
35
+ ```bash
36
+ npx expo run:ios
37
+ npx expo run:android
38
+ ```
39
+
19
40
  ## Using Other Package Managers
20
41
 
21
42
  ```bash
@@ -24,7 +45,7 @@ pnpm create twinbloc-app MyApp
24
45
  bun create twinbloc-app MyApp
25
46
  ```
26
47
 
27
- ## Options
48
+ ## CLI Options
28
49
 
29
50
  ```bash
30
51
  npx create-twinbloc-app@latest MyApp --example base
@@ -35,16 +56,23 @@ npx create-twinbloc-app@latest MyApp --pm pnpm
35
56
  npx create-twinbloc-app@latest MyApp --pm bun
36
57
  ```
37
58
 
38
- ## Running the App (Dev Client)
59
+ ### Example Variants
39
60
 
40
- This template uses a development build. After creating the project:
61
+ Only the base template ships in this repo. Use:
62
+
63
+ ```bash
64
+ npx create-twinbloc-app@latest MyApp --example base
65
+ ```
66
+
67
+ ## Running the App
68
+
69
+ This starter includes native modules, so you should use a development build instead of Expo Go.
41
70
 
42
71
  ```bash
43
- cd MyApp
44
72
  npm run start
45
73
  ```
46
74
 
47
- Then build and open a dev client:
75
+ Then run a dev client when you need native modules:
48
76
 
49
77
  ```bash
50
78
  npx expo run:ios
@@ -57,19 +85,58 @@ npx expo run:android
57
85
  MyApp/
58
86
  app/ # Expo Router routes
59
87
  assets/ # Images and icons
60
- src/ # App state and shared utilities
61
- app.json # Expo configuration
88
+ src/
89
+ api/ # Axios client and React Query helpers
90
+ components/ # UI components and providers
91
+ hooks/ # App hooks
92
+ lib/ # i18n, env, storage, utilities
93
+ store/ # Zustand stores
94
+ translations/ # i18n resource files
95
+ app.config.ts # Env-driven Expo config
96
+ global.css # NativeWind globals
62
97
  package.json # Scripts and dependencies
63
98
  tsconfig.json # TypeScript config
64
99
  ```
65
100
 
101
+ ## Environment Configuration
102
+
103
+ The template loads environment values from `.env.{APP_ENV}` and `.env` with `APP_ENV=development|staging|production`.
104
+
105
+ Required by default:
106
+
107
+ - `EXPO_PUBLIC_API_URL` for your API base URL
108
+
109
+ Optional overrides:
110
+
111
+ - `APP_NAME`, `APP_SLUG`, `APP_SCHEME`
112
+ - `APP_BUNDLE_ID_DEVELOPMENT`, `APP_BUNDLE_ID_STAGING`, `APP_BUNDLE_ID_PRODUCTION`
113
+ - `APP_PACKAGE_DEVELOPMENT`, `APP_PACKAGE_STAGING`, `APP_PACKAGE_PRODUCTION`
114
+
115
+ Values are validated on startup. If you update `.env` files and still see errors, restart the dev server with `-c` to clear cache.
116
+
117
+ ## Scripts
118
+
119
+ ```bash
120
+ npm run start # Expo dev server
121
+ npm run ios # Build iOS dev client
122
+ npm run android # Build Android dev client
123
+ npm run web # Run web build
124
+ npm run lint # Lint project
125
+ npm run test # Jest tests
126
+ npm run reset-project # Move starter to app-example and create a fresh app
127
+ ```
128
+
66
129
  ## Template Details
67
130
 
68
131
  - Location: `template/react-native-starter`
69
132
  - Framework: Expo SDK 54 + Expo Router
70
- - State: Zustand example in `src/state`
133
+ - Styling: NativeWind + Tailwind utilities
134
+ - State: Zustand stores in `src/store`
135
+ - Data: TanStack Query helpers in `src/api`
136
+ - i18n: `src/lib/i18n` and `src/translations`
71
137
 
72
138
  ## Troubleshooting
73
139
 
74
140
  - If install fails, retry with `--pm` to force a package manager.
75
141
  - If the folder is not empty, choose a new directory name.
142
+ - If your app launches but native modules crash, rebuild the dev client.
package/bin/cli.js CHANGED
@@ -68,6 +68,11 @@ const runInstall = (dir, pm) => {
68
68
 
69
69
  const brandPrimary = chalk.hex("#6CABDD");
70
70
  const brandDeep = chalk.hex("#1C2C5B");
71
+ const rnBlue = chalk.hex("#61DAFB");
72
+ const uiMuted = chalk.gray;
73
+ const uiAccent = chalk.hex("#9FD7F2");
74
+ const uiActive = chalk.hex("#88C6FF");
75
+ const uiSelected = chalk.hex("#6EDC91");
71
76
 
72
77
  const printBanner = () => {
73
78
  const lines = [
@@ -83,6 +88,7 @@ const printBanner = () => {
83
88
  console.log(paint(line));
84
89
  });
85
90
  console.log(brandPrimary("React Native Starter"));
91
+ console.log(rnBlue(" ⚛ React Native • Expo + Router • TypeScript • Zustand"));
86
92
  console.log("");
87
93
  };
88
94
 
@@ -113,9 +119,9 @@ const getExistingAgentKeys = async (rootDir) => {
113
119
  const renderAgentSelection = (choices, selectedKeys, activeIndex) => {
114
120
  output.write("\x1b[2J\x1b[0;0H");
115
121
  printBanner();
116
- console.log(brandPrimary.bold("Select agent configs to include:"));
117
- console.log(brandDeep("Use ↑/↓ to move, space to toggle, enter to confirm."));
118
- console.log(brandDeep("Press enter with nothing selected for none."));
122
+ console.log(brandPrimary.bold("Select agent configs to include"));
123
+ console.log(uiMuted("Use ↑/↓ to move, space to toggle, enter to confirm."));
124
+ console.log(uiMuted("Press enter with nothing selected for none."));
119
125
  console.log("");
120
126
 
121
127
  choices.forEach((choice, index) => {
@@ -124,7 +130,15 @@ const renderAgentSelection = (choices, selectedKeys, activeIndex) => {
124
130
  const cursor = isActive ? ">" : " ";
125
131
  const mark = isSelected ? "x" : " ";
126
132
  const line = `${cursor} [${mark}] ${choice.label}`;
127
- console.log(isActive ? brandPrimary.bold(line) : brandDeep(line));
133
+ if (isActive) {
134
+ console.log(uiActive.bold(line));
135
+ return;
136
+ }
137
+ if (isSelected) {
138
+ console.log(uiSelected(line));
139
+ return;
140
+ }
141
+ console.log(uiAccent(line));
128
142
  });
129
143
  };
130
144
 
@@ -230,16 +244,16 @@ const main = async () => {
230
244
  [
231
245
  brandPrimary.bold("Project created successfully."),
232
246
  "",
233
- brandDeep(`Agent configs: ${selectedLabels.length > 0 ? selectedLabels.join(", ") : "none"}`),
247
+ uiMuted(`Agent configs: ${selectedLabels.length > 0 ? selectedLabels.join(", ") : "none"}`),
234
248
  "",
235
- brandPrimary("Next steps:"),
236
- brandDeep(` cd ${appName}`),
237
- options.skipInstall ? brandDeep(" npm install") : null,
238
- brandDeep(" npm run start"),
249
+ brandPrimary("Next steps"),
250
+ uiAccent(` cd ${appName}`),
251
+ options.skipInstall ? uiAccent(" npm install") : null,
252
+ uiAccent(" npm run start"),
239
253
  "",
240
- brandPrimary("Then:"),
241
- brandDeep(" - Build a dev client (if you haven’t): npx expo run:ios / npx expo run:android"),
242
- brandDeep(" - Open the app from the dev client on your device or simulator"),
254
+ brandPrimary("Then"),
255
+ uiMuted(" - Build a dev client (if you haven’t): npx expo run:ios / npx expo run:android"),
256
+ uiMuted(" - Open the app from the dev client on your device or simulator"),
243
257
  ]
244
258
  .filter(Boolean)
245
259
  .join("\n"),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-twinbloc-app",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "React Native starter template with optional examples",
5
5
  "type": "module",
6
6
  "bin": {