create-lve 0.6.30 → 0.6.31

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 (46) hide show
  1. package/README.md +40 -0
  2. package/config.js +6 -200
  3. package/index.js +8 -14
  4. package/package.json +2 -1
  5. package/template-react/src/main.tsx +1 -0
  6. package/template-react/tsconfig.node.json +0 -1
  7. package/template-react/vite.config.ts +2 -1
  8. package/template-react-tanstackrouter/.env.example +0 -0
  9. package/template-react-tanstackrouter/.oxfmtrc.json +6 -0
  10. package/template-react-tanstackrouter/.oxlintrc.json +8 -0
  11. package/template-react-tanstackrouter/.vscode/extensions.json +3 -0
  12. package/template-react-tanstackrouter/.vscode/settings.json +74 -0
  13. package/template-react-tanstackrouter/README.md +13 -0
  14. package/template-react-tanstackrouter/index.html +14 -0
  15. package/template-react-tanstackrouter/package.json +38 -0
  16. package/template-react-tanstackrouter/pnpm-lock.yaml +1928 -0
  17. package/template-react-tanstackrouter/public/favicon.svg +1 -0
  18. package/template-react-tanstackrouter/public/icons.svg +24 -0
  19. package/template-react-tanstackrouter/src/assets/hero.png +0 -0
  20. package/template-react-tanstackrouter/src/assets/react.svg +1 -0
  21. package/template-react-tanstackrouter/src/assets/vite.svg +1 -0
  22. package/template-react-tanstackrouter/src/components/.gitkeep +0 -0
  23. package/template-react-tanstackrouter/src/components/ui/.gitkeep +0 -0
  24. package/template-react-tanstackrouter/src/features/.gitkeep +0 -0
  25. package/template-react-tanstackrouter/src/lib/.gitkeep +0 -0
  26. package/template-react-tanstackrouter/src/main.tsx +23 -0
  27. package/template-react-tanstackrouter/src/router.tsx +19 -0
  28. package/template-react-tanstackrouter/src/routes/__root.tsx +10 -0
  29. package/template-react-tanstackrouter/src/routes/_marketing-layout/about.tsx +14 -0
  30. package/template-react-tanstackrouter/src/routes/_marketing-layout/index.tsx +33 -0
  31. package/template-react-tanstackrouter/src/routes/_marketing-layout/route.tsx +36 -0
  32. package/template-react-tanstackrouter/src/routes/dashboard/index.tsx +14 -0
  33. package/template-react-tanstackrouter/src/routes/dashboard/route.tsx +33 -0
  34. package/template-react-tanstackrouter/src/routes/dashboard/settings.tsx +14 -0
  35. package/template-react-tanstackrouter/src/services/.gitkeep +0 -0
  36. package/template-react-tanstackrouter/src/state/.gitkeep +0 -0
  37. package/template-react-tanstackrouter/src/styles.css +79 -0
  38. package/template-react-tanstackrouter/tsconfig.app.json +32 -0
  39. package/template-react-tanstackrouter/tsconfig.json +4 -0
  40. package/template-react-tanstackrouter/tsconfig.node.json +23 -0
  41. package/template-react-tanstackrouter/vite.config.ts +19 -0
  42. package/template-vue/src/main.ts +1 -0
  43. package/template-vue/src/style.css +1 -0
  44. package/template-vue/src/views/HomeView.vue +1 -1
  45. package/template-vue/tsconfig.node.json +1 -4
  46. package/template-vue/vite.config.ts +2 -4
package/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # create-lve
2
+
3
+ THE ULTRA-FAST FRONTEND STACK
4
+
5
+ ```bash
6
+ npx create-lve
7
+ ```
8
+
9
+ ## Options
10
+
11
+ | Template | Description |
12
+ | --- | --- |
13
+ | React 19 | react-router + vite-plus |
14
+ | React 19 | TanStack Router + Vite 8 |
15
+ | Vue 3 | vue-router + vite-plus |
16
+
17
+ All templates ship with **Tailwind CSS v4** out of the box.
18
+
19
+ ## Quick Start
20
+
21
+ ```bash
22
+ # Interactive mode
23
+ npx create-lve
24
+
25
+ # Default (React 19 + react-router + Tailwind)
26
+ npx create-lve my-app
27
+
28
+ # Skip all prompts
29
+ npx create-lve --default my-app
30
+ ```
31
+
32
+ ## What's Inside
33
+
34
+ - React 19 / Vue 3
35
+ - Tailwind CSS v4
36
+ - TypeScript
37
+ - [vite-plus](https://github.com/voidzero-dev/vite-plus) (React & Vue templates) or Vite 8 (TanStack Router template)
38
+ - React Compiler (via `babel-plugin-react-compiler`)
39
+ - oxfmt + oxlint
40
+ - pnpm
package/config.js CHANGED
@@ -7,88 +7,7 @@ import { execSync, spawn } from 'node:child_process'
7
7
 
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url))
9
9
 
10
- const BASE_STYLE = `@layer base {
11
- /* Scrollbar */
12
- * {
13
- scrollbar-width: thin;
14
- scrollbar-color: rgba(0, 0, 0, 0.2) transparent;
15
- }
16
- ::-webkit-scrollbar {
17
- width: 6px;
18
- height: 6px;
19
- }
20
- ::-webkit-scrollbar-thumb {
21
- background: rgba(0, 0, 0, 0.2);
22
- border-radius: 3px;
23
- }
24
- ::-webkit-scrollbar-track {
25
- background: transparent;
26
- }
27
- .dark * {
28
- scrollbar-color: rgba(255, 255, 255, 0.15) transparent;
29
- }
30
- .dark ::-webkit-scrollbar-thumb {
31
- background: rgba(255, 255, 255, 0.15);
32
- }
33
-
34
- /* 文本渲染 */
35
- html {
36
- -webkit-font-smoothing: antialiased;
37
- -moz-osx-font-smoothing: grayscale;
38
- text-rendering: optimizeLegibility;
39
- }
40
-
41
- /* 选中色 */
42
- ::selection {
43
- background: rgba(59, 130, 246, 0.2);
44
- }
45
-
46
- /* 触摸优化 */
47
- body {
48
- -webkit-tap-highlight-color: transparent;
49
- }
50
- }
51
-
52
- /* 链接和图片禁止拖拽 + 长按菜单 + 点击高亮 */
53
- a,
54
- img {
55
- -webkit-user-drag: none;
56
- -webkit-tap-highlight-color: transparent;
57
- -webkit-touch-callout: none;
58
- }
59
-
60
- /* input number 去掉上下箭头 */
61
- input[type='number']::-webkit-inner-spin-button,
62
- input[type='number']::-webkit-outer-spin-button {
63
- -webkit-appearance: none;
64
- margin: 0;
65
- }
66
-
67
- /* textarea 禁止拖拽调整大小 */
68
- textarea {
69
- resize: none;
70
- }
71
-
72
- /* details/summary 去掉默认三角 */
73
- summary {
74
- list-style: none;
75
- }
76
- summary::marker {
77
- display: none;
78
- content: '';
79
- }
80
-
81
- /* focus 焦点环 */
82
- a:focus-visible {
83
- outline: 2px solid var(--color-primary, #3b82f6);
84
- outline-offset: 2px;
85
- border-radius: 2px;
86
- }
87
- `
88
-
89
- const vitePlusDeps = (isUno) => ({
90
- dependencies: isUno ? { '@unocss/reset': 'latest' } : undefined,
91
- devDependencies: isUno ? { unocss: 'latest' } : undefined,
10
+ const vitePlusDeps = () => ({
92
11
  overrides: {
93
12
  vite: 'npm:@voidzero-dev/vite-plus-core@latest',
94
13
  vitest: 'npm:@voidzero-dev/vite-plus-test@latest',
@@ -97,97 +16,10 @@ const vitePlusDeps = (isUno) => ({
97
16
 
98
17
  const FRAMEWORK_CONFIG = {
99
18
  react: { deps: vitePlusDeps },
19
+ 'react-tanstackrouter': { deps: () => ({}) },
100
20
  vue: { deps: vitePlusDeps },
101
21
  }
102
22
 
103
- const CSS_STRATEGIES = {
104
- unocss: {
105
- pluginImport: "import UnoCSS from 'unocss/vite'\n",
106
- pluginCode: 'UnoCSS(), ',
107
- entryImport: "import '@unocss/reset/tailwind.css'\nimport 'virtual:uno.css'\n",
108
- async setup(ctx) {
109
- const unoConfig = `
110
- import {
111
- defineConfig,
112
- presetWind3,
113
- transformerCompileClass,
114
- type SourceCodeTransformer,
115
- } from 'unocss'
116
- import { createHash } from 'node:crypto'
117
-
118
- declare const process: { env: { NODE_ENV: string } }
119
- const isBuild = process.env.NODE_ENV === 'production'
120
-
121
- export default defineConfig({
122
- presets: [presetWind3()],
123
- transformers: (isBuild
124
- ? [
125
- {
126
- name: 'auto-uno-injector',
127
- enforce: 'pre',
128
- idFilter(id) {
129
- return /\\.[tj]sx$|\\.vue$/.test(id)
130
- },
131
- async transform(code) {
132
- const s = code as any
133
- const classRegex = /(?:class|className)=["']([^"']+)["']/g
134
- let match
135
- while ((match = classRegex.exec(s.original))) {
136
- const content = match[1]
137
- if (content.trim() && !content.includes(':uno:')) {
138
- const insertPos = match.index + match[0].indexOf(content)
139
- s.appendLeft(insertPos, ':uno: ')
140
- }
141
- }
142
- },
143
- },
144
- transformerCompileClass({
145
- classPrefix: '',
146
- hashFn: (str) => {
147
- // return createHash('md5').update(str).digest('hex').slice(0, 8)
148
- const hash = createHash('md5').update(str).digest('hex').slice(0, 8)
149
- return /^\\d/.test(hash) ? 'v' + hash.slice(1, 8) : hash.slice(0, 8)
150
- },
151
- keepUnknown: true,
152
- }),
153
- ]
154
- : []) as SourceCodeTransformer[],
155
- })
156
-
157
- `.trim()
158
- await fs.writeFile(path.join(ctx.targetDir, 'uno.config.ts'), unoConfig + '\n')
159
-
160
- const tsconfigPath = path.join(ctx.targetDir, 'tsconfig.node.json')
161
- if (fs.existsSync(tsconfigPath)) {
162
- try {
163
- let content = await fs.readFile(tsconfigPath, 'utf-8')
164
-
165
- if (content.includes('/* UNO_CONFIG */')) {
166
- content = content.replace('/* UNO_CONFIG */', ', "uno.config.ts"')
167
- await fs.writeFile(tsconfigPath, content)
168
- }
169
- } catch {}
170
- }
171
-
172
- const stylePath = path.join(ctx.targetDir, 'src/style.css')
173
- if (fs.existsSync(stylePath)) await fs.remove(stylePath)
174
- },
175
- },
176
- tailwind: {
177
- pluginImport: "import tailwindcss from '@tailwindcss/vite'\n",
178
- pluginCode: 'tailwindcss(), ',
179
- entryImport: "import './style.css'\n",
180
- async setup(ctx) {
181
- // style.css 已由 applyProjectTransform 写入,此处仅兜底
182
- const stylePath = path.join(ctx.targetDir, 'src/style.css')
183
- if (!fs.existsSync(stylePath)) {
184
- await fs.ensureDir(path.dirname(stylePath))
185
- await fs.writeFile(stylePath, `@import "tailwindcss";`)
186
- }
187
- },
188
- },
189
- }
190
-
191
23
  async function resolveLatestVersions(pkgPath) {
192
24
  const pkg = await fs.readJson(pkgPath)
193
25
  const sections = ['dependencies', 'devDependencies']
@@ -232,19 +64,15 @@ async function runTask(command, args, cwd) {
232
64
  }
233
65
 
234
66
  async function applyProjectTransform(ctx) {
235
- const { targetDir, framework, css, isUno } = ctx
67
+ const { targetDir, framework } = ctx
236
68
 
237
69
  const pkgPath = path.join(targetDir, 'package.json')
238
70
  const pkg = await fs.readJson(pkgPath)
239
71
  const config = FRAMEWORK_CONFIG[framework]
240
72
  pkg.name = ctx.name
241
- const extraConfig = config.deps(isUno)
242
- pkg.dependencies = { ...pkg.dependencies, ...extraConfig.dependencies }
243
- pkg.devDependencies = { ...pkg.devDependencies, ...extraConfig.devDependencies }
244
- if (isUno) {
245
- delete pkg.devDependencies?.['tailwindcss']
246
- delete pkg.devDependencies?.['@tailwindcss/vite']
247
- }
73
+ const extraConfig = config.deps()
74
+ if (extraConfig.dependencies) pkg.dependencies = { ...pkg.dependencies, ...extraConfig.dependencies }
75
+ if (extraConfig.devDependencies) pkg.devDependencies = { ...pkg.devDependencies, ...extraConfig.devDependencies }
248
76
  if (extraConfig.overrides) pkg.overrides = { ...pkg.overrides, ...extraConfig.overrides }
249
77
  try {
250
78
  const version = execSync('pnpm --version', { encoding: 'utf-8', timeout: 5000 }).trim()
@@ -260,28 +88,6 @@ async function applyProjectTransform(ctx) {
260
88
  indexContent = indexContent.replace(/<title>.*?<\/title>/, `<title>${ctx.name}</title>`)
261
89
  await fs.writeFile(indexPath, indexContent)
262
90
  }
263
-
264
- const strategy = CSS_STRATEGIES[css]
265
- const isVue = framework === 'vue'
266
- const paths = {
267
- main: path.join(targetDir, isVue ? 'src/main.ts' : 'src/main.tsx'),
268
- vite: path.join(targetDir, 'vite.config.ts'),
269
- }
270
-
271
- let viteContent = await fs.readFile(paths.vite, 'utf-8')
272
- if (!viteContent.includes(strategy.pluginImport.trim())) {
273
- viteContent = strategy.pluginImport + viteContent
274
- }
275
- viteContent = viteContent.replace('/* VITE_PLUS_PLUGINS */', strategy.pluginCode)
276
- await fs.writeFile(paths.vite, viteContent)
277
-
278
- let mainContent = await fs.readFile(paths.main, 'utf-8')
279
- if (!mainContent.includes(strategy.entryImport.trim())) {
280
- mainContent = strategy.entryImport + mainContent
281
- }
282
- await fs.writeFile(paths.main, mainContent)
283
-
284
- await strategy.setup(ctx)
285
91
  }
286
92
 
287
93
  async function cleanupTemplate(ctx) {
package/index.js CHANGED
@@ -54,7 +54,7 @@ async function main() {
54
54
  shouldOverwrite = await p.confirm({ message: `目录已存在,是否清空?`, initialValue: false })
55
55
  if (p.isCancel(shouldOverwrite)) onCancel()
56
56
  }
57
- project = { path: name, framework: 'react', cssEngine: 'tailwind', shouldOverwrite }
57
+ project = { path: name, framework: 'react', shouldOverwrite }
58
58
  } else {
59
59
  // 交互模式
60
60
  project = await p.group(
@@ -81,19 +81,15 @@ async function main() {
81
81
  p.select({
82
82
  message: '选择框架',
83
83
  options: [
84
- { value: 'react', label: 'React 19', hint: '' },
84
+ { value: 'react', label: 'React+ RR+ VP', hint: 'react-router' },
85
+ {
86
+ value: 'react-tanstackrouter',
87
+ label: 'React+ Vite + TR',
88
+ hint: 'TanStack Router',
89
+ },
85
90
  { value: 'vue', label: 'Vue 3', hint: '' },
86
91
  ],
87
92
  }),
88
-
89
- cssEngine: () =>
90
- p.select({
91
- message: '选择 CSS',
92
- options: [
93
- { value: 'tailwind', label: 'Tailwind v4' },
94
- { value: 'unocss', label: 'UnoCSS' },
95
- ],
96
- }),
97
93
  },
98
94
  { onCancel },
99
95
  )
@@ -102,13 +98,11 @@ async function main() {
102
98
  const ctx = {
103
99
  name: project.path,
104
100
  framework: project.framework,
105
- css: project.cssEngine,
106
101
  targetDir: path.resolve(process.cwd(), project.path),
107
102
  templateDir: path.resolve(__dirname, `template-${project.framework}`),
108
- isUno: project.cssEngine === 'unocss',
109
103
  pkgManager: 'pnpm',
110
104
  devCmd: 'pnpm dev',
111
- fmtCmd: 'vp fmt',
105
+ fmtCmd: project.framework === 'react-tanstackrouter' ? 'pnpm fmt' : 'vp fmt',
112
106
  }
113
107
 
114
108
  const s = p.spinner()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-lve",
3
- "version": "0.6.30",
3
+ "version": "0.6.31",
4
4
  "bin": {
5
5
  "create-lve": "index.js"
6
6
  },
@@ -8,6 +8,7 @@
8
8
  "index.js",
9
9
  "config.js",
10
10
  "template-react",
11
+ "template-react-tanstackrouter",
11
12
  "template-vue",
12
13
  "!**/node_modules"
13
14
  ],
@@ -1,5 +1,6 @@
1
1
  import { StrictMode } from 'react'
2
2
  import { createRoot } from 'react-dom/client'
3
+ import './style.css'
3
4
  import { Providers } from './app/providers'
4
5
  import { getRouter } from './app/router'
5
6
  import { RouterProvider } from 'react-router'
@@ -24,6 +24,5 @@
24
24
  },
25
25
  "include": [
26
26
  "vite.config.ts"
27
- /* UNO_CONFIG */
28
27
  ]
29
28
  }
@@ -1,5 +1,6 @@
1
1
  import { defineConfig, loadEnv, lazyPlugins, type Plugin } from 'vite-plus'
2
2
  import react, { reactCompilerPreset } from '@vitejs/plugin-react'
3
+ import tailwindcss from '@tailwindcss/vite'
3
4
 
4
5
  const mode = process.env.NODE_ENV || 'development'
5
6
  const env = loadEnv(mode, process.cwd(), '')
@@ -12,7 +13,7 @@ export default defineConfig({
12
13
  '*': 'vp check --fix',
13
14
  },
14
15
  plugins: [
15
- /* VITE_PLUS_PLUGINS */
16
+ tailwindcss(),
16
17
  react(),
17
18
  // lazyPlugins 返回类型与 Vite plugins 字段类型不兼容
18
19
  // 上游 issue: vitejs/vite#22085,官方确认为已知问题
File without changes
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "./node_modules/oxfmt/configuration_schema.json",
3
+ "ignorePatterns": [],
4
+ "semi": false,
5
+ "singleQuote": true
6
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "$schema": "./node_modules/oxlint/configuration_schema.json",
3
+ "plugins": ["react", "typescript", "oxc"],
4
+ "rules": {
5
+ "react/rules-of-hooks": "error",
6
+ "react/only-export-components": ["off", { "allowConstantExport": true }]
7
+ }
8
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "recommendations": ["TypeScriptTeam.native-preview"]
3
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "files.watcherExclude": {
3
+ "**/routeTree.gen.ts": true
4
+ },
5
+ "search.exclude": {
6
+ "**/routeTree.gen.ts": true
7
+ },
8
+ "files.readonlyInclude": {
9
+ "**/routeTree.gen.ts": true
10
+ },
11
+
12
+ // ==================== Formatter (OXC) ====================
13
+ "editor.defaultFormatter": "oxc.oxc-vscode",
14
+ "editor.formatOnSave": true,
15
+ "editor.formatOnSaveMode": "file",
16
+ "oxc.enable.oxfmt": true,
17
+
18
+ // 语言特定 Formatter
19
+ "[javascript]": {
20
+ "editor.defaultFormatter": "oxc.oxc-vscode"
21
+ },
22
+ "[typescript]": {
23
+ "editor.defaultFormatter": "oxc.oxc-vscode"
24
+ },
25
+ "[typescriptreact]": {
26
+ "editor.defaultFormatter": "oxc.oxc-vscode"
27
+ },
28
+ "[javascriptreact]": {
29
+ "editor.defaultFormatter": "oxc.oxc-vscode"
30
+ },
31
+ "[css]": {
32
+ "editor.defaultFormatter": "oxc.oxc-vscode"
33
+ },
34
+ "[tailwindcss]": {
35
+ "editor.defaultFormatter": "oxc.oxc-vscode"
36
+ },
37
+ "[json]": {
38
+ "editor.defaultFormatter": "oxc.oxc-vscode"
39
+ },
40
+ "[jsonc]": {
41
+ "editor.defaultFormatter": "oxc.oxc-vscode"
42
+ },
43
+ "[html]": {
44
+ "editor.defaultFormatter": "oxc.oxc-vscode"
45
+ },
46
+ "[vue]": {
47
+ "editor.defaultFormatter": "oxc.oxc-vscode"
48
+ },
49
+
50
+ // ==================== Tailwind + shadcn/ui(强烈推荐)===================
51
+ "tailwindCSS.experimental.classRegex": [["cn\\(([^)]*)\\)", "(?:'|\"|`)([^']*)(?:'|\"|`)"]],
52
+ "tailwindCSS.includeLanguages": {
53
+ "typescript": "html",
54
+ "typescriptreact": "html"
55
+ },
56
+ "editor.quickSuggestions": {
57
+ "strings": "on"
58
+ },
59
+
60
+ // ==================== 其他项目通用 ====================
61
+ "git.openRepositoryInParentFolders": "always",
62
+ "js/ts.updateImportsOnFileMove.enabled": "always",
63
+ "diffEditor.ignoreTrimWhitespace": true,
64
+ "diffEditor.hideUnchangedRegions.enabled": true,
65
+ "editor.inlayHints.enabled": "on",
66
+
67
+ // ==================== TypeScript 7 (tsgo) ====================
68
+ "js/ts.experimental.useTsgo": true,
69
+
70
+ "js/ts.tsserver.watchOptions": {
71
+ "watchFile": "dynamicPriorityPolling",
72
+ "watchDirectory": "dynamicPriorityPolling"
73
+ }
74
+ }
@@ -0,0 +1,13 @@
1
+ # React Starter
2
+
3
+ A modern React application starter.
4
+
5
+ ## Stack
6
+
7
+ - React 19
8
+ - Vite 8
9
+ - TypeScript
10
+ - TanStack Router
11
+ - Tailwind CSS
12
+ - oxlint
13
+ - oxfmt
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>vite-project</title>
8
+ </head>
9
+
10
+ <body>
11
+ <div id="react-root"></div>
12
+ <script type="module" src="/src/main.tsx"></script>
13
+ </body>
14
+ </html>
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "vite-project",
3
+ "version": "0.0.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "imports": {
7
+ "#/*": "./src/*"
8
+ },
9
+ "scripts": {
10
+ "dev": "vite",
11
+ "build": "tsc -b && vite build",
12
+ "fmt": "oxfmt",
13
+ "lint": "oxlint",
14
+ "preview": "vite preview"
15
+ },
16
+ "dependencies": {
17
+ "@tanstack/react-router": "^1.170.17",
18
+ "react": "^19.2.7",
19
+ "react-dom": "^19.2.7"
20
+ },
21
+ "devDependencies": {
22
+ "@babel/core": "^7.29.7",
23
+ "@rolldown/plugin-babel": "^0.2.3",
24
+ "@tailwindcss/vite": "^4.3.2",
25
+ "@tanstack/router-plugin": "^1.168.19",
26
+ "@types/babel__core": "^7.20.5",
27
+ "@types/node": "^24.13.2",
28
+ "@types/react": "^19.2.17",
29
+ "@types/react-dom": "^19.2.3",
30
+ "@vitejs/plugin-react": "^6.0.3",
31
+ "babel-plugin-react-compiler": "^1.0.0",
32
+ "oxfmt": "^0.58.0",
33
+ "oxlint": "^1.71.0",
34
+ "tailwindcss": "^4.3.2",
35
+ "typescript": "~6.0.2",
36
+ "vite": "^8.1.1"
37
+ }
38
+ }