create-heliumts-app 0.2.5
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/README.md +67 -0
- package/bin/index.js +5 -0
- package/package.json +40 -0
- package/src/index.js +245 -0
- package/templates/basic/README.md +44 -0
- package/templates/basic/eslint.config.js +23 -0
- package/templates/basic/helium.config.ts +21 -0
- package/templates/basic/index.html +13 -0
- package/templates/basic/package-lock.json +3718 -0
- package/templates/basic/package.json +30 -0
- package/templates/basic/public/helium.png +0 -0
- package/templates/basic/src/App.tsx +5 -0
- package/templates/basic/src/components/HeliumLogo.tsx +9 -0
- package/templates/basic/src/pages/_layout.tsx +3 -0
- package/templates/basic/src/pages/index.tsx +69 -0
- package/templates/basic/src/server/tasks.ts +26 -0
- package/templates/basic/src/styles.css +181 -0
- package/templates/basic/src/types/heliumts-server.d.ts +13 -0
- package/templates/basic/tsconfig.app.json +28 -0
- package/templates/basic/tsconfig.json +7 -0
- package/templates/basic/tsconfig.node.json +26 -0
- package/templates/basic/vite.config.ts +8 -0
- package/templates/tailwind/README.md +49 -0
- package/templates/tailwind/eslint.config.js +23 -0
- package/templates/tailwind/helium.config.ts +21 -0
- package/templates/tailwind/index.html +13 -0
- package/templates/tailwind/package-lock.json +4286 -0
- package/templates/tailwind/package.json +32 -0
- package/templates/tailwind/public/helium.png +0 -0
- package/templates/tailwind/src/App.tsx +5 -0
- package/templates/tailwind/src/components/HeliumLogo.tsx +11 -0
- package/templates/tailwind/src/pages/_layout.tsx +3 -0
- package/templates/tailwind/src/pages/index.tsx +87 -0
- package/templates/tailwind/src/server/tasks.ts +26 -0
- package/templates/tailwind/src/styles.css +7 -0
- package/templates/tailwind/src/types/heliumts-server.d.ts +13 -0
- package/templates/tailwind/tsconfig.app.json +28 -0
- package/templates/tailwind/tsconfig.json +7 -0
- package/templates/tailwind/tsconfig.node.json +26 -0
- package/templates/tailwind/vite.config.ts +9 -0
package/README.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# create-heliumts-app
|
|
2
|
+
|
|
3
|
+
Create [HeliumTS](https://github.com/heliobentes/heliumts) apps with one command.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx create-heliumts-app my-app
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or to scaffold in the current directory:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npx create-heliumts-app .
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### Options
|
|
18
|
+
|
|
19
|
+
| Flag | Description |
|
|
20
|
+
|------|-------------|
|
|
21
|
+
| `--tailwind` | Use Tailwind CSS template (skips prompt) |
|
|
22
|
+
| `--no-tailwind` | Use basic template without Tailwind (skips prompt) |
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Use Tailwind CSS (default, skips prompt)
|
|
26
|
+
npx create-heliumts-app my-app --tailwind
|
|
27
|
+
|
|
28
|
+
# Use basic template without Tailwind (skips prompt)
|
|
29
|
+
npx create-heliumts-app my-app --no-tailwind
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## What it does
|
|
33
|
+
|
|
34
|
+
1. Asks if you want to use **Tailwind CSS** (defaults to Yes)
|
|
35
|
+
2. Scaffolds a complete HeliumTS project with one of two templates:
|
|
36
|
+
- `tailwind` - HeliumTS with Tailwind CSS pre-configured (default)
|
|
37
|
+
- `basic` - Standard HeliumTS setup
|
|
38
|
+
3. Automatically runs `npm install`
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Node.js 18.0.0 or later
|
|
43
|
+
- npm, yarn, or pnpm
|
|
44
|
+
|
|
45
|
+
## After Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
cd my-app
|
|
49
|
+
npm run dev
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Available Scripts
|
|
53
|
+
|
|
54
|
+
| Command | Description |
|
|
55
|
+
|---------|-------------|
|
|
56
|
+
| `npm run dev` | Start development server |
|
|
57
|
+
| `npm run build` | Build for production |
|
|
58
|
+
| `npm run start` | Start production server |
|
|
59
|
+
|
|
60
|
+
## Learn More
|
|
61
|
+
|
|
62
|
+
- [HeliumTS Documentation](https://heliumts.com/docs)
|
|
63
|
+
- [HeliumTS GitHub](https://github.com/heliobentes/heliumts)
|
|
64
|
+
|
|
65
|
+
## License
|
|
66
|
+
|
|
67
|
+
MIT
|
package/bin/index.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-heliumts-app",
|
|
3
|
+
"version": "0.2.5",
|
|
4
|
+
"description": "Create HeliumTS apps with one command",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-heliumts-app": "./bin/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"test": "node bin/index.js test-app"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"heliumts",
|
|
15
|
+
"react",
|
|
16
|
+
"vite",
|
|
17
|
+
"fullstack",
|
|
18
|
+
"typescript",
|
|
19
|
+
"cli",
|
|
20
|
+
"create-app"
|
|
21
|
+
],
|
|
22
|
+
"author": "Helio Bentes",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/heliobentes/create-heliumts-app.git"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/heliobentes/create-heliumts-app/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://heliumts.com",
|
|
32
|
+
"files": [
|
|
33
|
+
"bin",
|
|
34
|
+
"src",
|
|
35
|
+
"templates"
|
|
36
|
+
],
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18.0.0"
|
|
39
|
+
}
|
|
40
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as readline from 'readline';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
9
|
+
|
|
10
|
+
const COLORS = {
|
|
11
|
+
reset: '\x1b[0m',
|
|
12
|
+
bright: '\x1b[1m',
|
|
13
|
+
dim: '\x1b[2m',
|
|
14
|
+
red: '\x1b[31m',
|
|
15
|
+
green: '\x1b[32m',
|
|
16
|
+
yellow: '\x1b[33m',
|
|
17
|
+
blue: '\x1b[34m',
|
|
18
|
+
magenta: '\x1b[35m',
|
|
19
|
+
cyan: '\x1b[36m',
|
|
20
|
+
white: '\x1b[37m'
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
function log(message, color = '') {
|
|
24
|
+
console.log(`${color}${message}${COLORS.reset}`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function logSuccess(message) {
|
|
28
|
+
log(`✓ ${message}`, COLORS.green);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function logError(message) {
|
|
32
|
+
log(`✗ ${message}`, COLORS.red);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function logInfo(message) {
|
|
36
|
+
log(`ℹ ${message}`, COLORS.cyan);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function printBanner() {
|
|
40
|
+
console.log('');
|
|
41
|
+
log('╔═══════════════════════════════════════════╗', COLORS.cyan);
|
|
42
|
+
log('║ ║', COLORS.cyan);
|
|
43
|
+
log('║ 🚀 Create HeliumTS App 🚀 ║', COLORS.cyan);
|
|
44
|
+
log('║ ║', COLORS.cyan);
|
|
45
|
+
log('╚═══════════════════════════════════════════╝', COLORS.cyan);
|
|
46
|
+
console.log('');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function askQuestion(rl, question) {
|
|
50
|
+
return new Promise((resolve) => {
|
|
51
|
+
rl.question(question, (answer) => {
|
|
52
|
+
resolve(answer.trim());
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function copyDirectory(src, dest) {
|
|
58
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
59
|
+
|
|
60
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
61
|
+
|
|
62
|
+
for (const entry of entries) {
|
|
63
|
+
const srcPath = path.join(src, entry.name);
|
|
64
|
+
const destPath = path.join(dest, entry.name);
|
|
65
|
+
|
|
66
|
+
if (entry.isDirectory()) {
|
|
67
|
+
copyDirectory(srcPath, destPath);
|
|
68
|
+
} else {
|
|
69
|
+
fs.copyFileSync(srcPath, destPath);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isDirectoryEmpty(dirPath) {
|
|
75
|
+
if (!fs.existsSync(dirPath)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const files = fs.readdirSync(dirPath);
|
|
80
|
+
// Ignore hidden files like .git, .DS_Store
|
|
81
|
+
const visibleFiles = files.filter(f => !f.startsWith('.'));
|
|
82
|
+
return visibleFiles.length === 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function parseArgs(args) {
|
|
86
|
+
const result = {
|
|
87
|
+
projectName: null,
|
|
88
|
+
tailwind: null // null means ask, true means use tailwind, false means skip tailwind
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
for (const arg of args) {
|
|
92
|
+
if (arg === '--tailwind') {
|
|
93
|
+
result.tailwind = true;
|
|
94
|
+
} else if (arg === '--no-tailwind') {
|
|
95
|
+
result.tailwind = false;
|
|
96
|
+
} else if (!arg.startsWith('-')) {
|
|
97
|
+
result.projectName = arg;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export async function createApp() {
|
|
105
|
+
printBanner();
|
|
106
|
+
|
|
107
|
+
// Get project name from command line arguments
|
|
108
|
+
const args = process.argv.slice(2);
|
|
109
|
+
const { projectName, tailwind: tailwindFlag } = parseArgs(args);
|
|
110
|
+
|
|
111
|
+
if (!projectName) {
|
|
112
|
+
logError('Please specify the project directory:');
|
|
113
|
+
console.log('');
|
|
114
|
+
log(' npx create-heliumts-app <project-directory>', COLORS.dim);
|
|
115
|
+
console.log('');
|
|
116
|
+
log('For example:', COLORS.dim);
|
|
117
|
+
log(' npx create-heliumts-app my-helium-app', COLORS.dim);
|
|
118
|
+
log(' npx create-heliumts-app my-helium-app --tailwind', COLORS.dim);
|
|
119
|
+
log(' npx create-heliumts-app .', COLORS.dim);
|
|
120
|
+
console.log('');
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Resolve the target directory
|
|
125
|
+
const isCurrentDir = projectName === '.';
|
|
126
|
+
const targetDir = isCurrentDir
|
|
127
|
+
? process.cwd()
|
|
128
|
+
: path.resolve(process.cwd(), projectName);
|
|
129
|
+
|
|
130
|
+
const displayName = isCurrentDir ? 'current directory' : projectName;
|
|
131
|
+
|
|
132
|
+
// Check if directory is empty
|
|
133
|
+
if (!isDirectoryEmpty(targetDir)) {
|
|
134
|
+
logError(`The directory "${displayName}" is not empty.`);
|
|
135
|
+
log('Please choose an empty directory or remove existing files.', COLORS.dim);
|
|
136
|
+
console.log('');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Create readline interface for user input
|
|
141
|
+
const rl = readline.createInterface({
|
|
142
|
+
input: process.stdin,
|
|
143
|
+
output: process.stdout
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
// Determine if we should use Tailwind
|
|
148
|
+
let useTailwind;
|
|
149
|
+
|
|
150
|
+
if (tailwindFlag !== null) {
|
|
151
|
+
// Flag was provided, use it directly
|
|
152
|
+
useTailwind = tailwindFlag;
|
|
153
|
+
log(`Creating a new HeliumTS app in ${COLORS.cyan}${targetDir}${COLORS.reset}`);
|
|
154
|
+
console.log('');
|
|
155
|
+
logInfo(`Using ${useTailwind ? 'Tailwind CSS' : 'basic'} template (from flag)...`);
|
|
156
|
+
} else {
|
|
157
|
+
// Ask the user
|
|
158
|
+
log(`Creating a new HeliumTS app in ${COLORS.cyan}${targetDir}${COLORS.reset}`);
|
|
159
|
+
console.log('');
|
|
160
|
+
|
|
161
|
+
const tailwindAnswer = await askQuestion(
|
|
162
|
+
rl,
|
|
163
|
+
`${COLORS.yellow}?${COLORS.reset} Do you want to use Tailwind CSS? ${COLORS.dim}(Y/n)${COLORS.reset} `
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Default is YES (Tailwind)
|
|
167
|
+
useTailwind = tailwindAnswer.toLowerCase() !== 'n' && tailwindAnswer.toLowerCase() !== 'no';
|
|
168
|
+
console.log('');
|
|
169
|
+
logInfo(`Using ${useTailwind ? 'Tailwind CSS' : 'basic'} template...`);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const templateName = useTailwind ? 'tailwind' : 'basic';
|
|
173
|
+
|
|
174
|
+
// Get template path
|
|
175
|
+
const templatesDir = path.join(__dirname, '..', 'templates');
|
|
176
|
+
const templatePath = path.join(templatesDir, templateName);
|
|
177
|
+
|
|
178
|
+
// Check if template exists
|
|
179
|
+
if (!fs.existsSync(templatePath)) {
|
|
180
|
+
logError(`Template "${templateName}" not found at ${templatePath}`);
|
|
181
|
+
log('Please make sure the templates are properly installed.', COLORS.dim);
|
|
182
|
+
process.exit(1);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Copy template to target directory
|
|
186
|
+
logInfo('Scaffolding project...');
|
|
187
|
+
copyDirectory(templatePath, targetDir);
|
|
188
|
+
|
|
189
|
+
// Update package.json with project name
|
|
190
|
+
const packageJsonPath = path.join(targetDir, 'package.json');
|
|
191
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
192
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
193
|
+
packageJson.name = isCurrentDir ? path.basename(targetDir) : projectName;
|
|
194
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
logSuccess('Project scaffolded successfully!');
|
|
198
|
+
|
|
199
|
+
// Install dependencies
|
|
200
|
+
console.log('');
|
|
201
|
+
logInfo('Installing dependencies...');
|
|
202
|
+
console.log('');
|
|
203
|
+
|
|
204
|
+
try {
|
|
205
|
+
execSync('npm install', {
|
|
206
|
+
cwd: targetDir,
|
|
207
|
+
stdio: 'inherit'
|
|
208
|
+
});
|
|
209
|
+
console.log('');
|
|
210
|
+
logSuccess('Dependencies installed successfully!');
|
|
211
|
+
} catch (error) {
|
|
212
|
+
logError('Failed to install dependencies.');
|
|
213
|
+
log('Please run "npm install" manually in the project directory.', COLORS.dim);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Print success message
|
|
217
|
+
console.log('');
|
|
218
|
+
log('═══════════════════════════════════════════', COLORS.green);
|
|
219
|
+
logSuccess('Your HeliumTS app is ready!');
|
|
220
|
+
log('═══════════════════════════════════════════', COLORS.green);
|
|
221
|
+
console.log('');
|
|
222
|
+
|
|
223
|
+
log('Next steps:', COLORS.bright);
|
|
224
|
+
console.log('');
|
|
225
|
+
|
|
226
|
+
if (!isCurrentDir) {
|
|
227
|
+
log(` cd ${projectName}`, COLORS.cyan);
|
|
228
|
+
}
|
|
229
|
+
log(' npm run dev', COLORS.cyan);
|
|
230
|
+
console.log('');
|
|
231
|
+
|
|
232
|
+
log('Available commands:', COLORS.bright);
|
|
233
|
+
console.log('');
|
|
234
|
+
log(' npm run dev - Start development server', COLORS.dim);
|
|
235
|
+
log(' npm run build - Build for production', COLORS.dim);
|
|
236
|
+
log(' npm run start - Start production server', COLORS.dim);
|
|
237
|
+
console.log('');
|
|
238
|
+
|
|
239
|
+
log('Happy coding! 🎉', COLORS.magenta);
|
|
240
|
+
console.log('');
|
|
241
|
+
|
|
242
|
+
} finally {
|
|
243
|
+
rl.close();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# HeliumTS App
|
|
2
|
+
|
|
3
|
+
This is a [HeliumTS](https://heliumts.com) project bootstrapped with `create-heliumts-app`.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
First, install the dependencies:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install
|
|
11
|
+
# or
|
|
12
|
+
yarn
|
|
13
|
+
# or
|
|
14
|
+
pnpm install
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Then, run the development server:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm run dev
|
|
21
|
+
# or
|
|
22
|
+
yarn dev
|
|
23
|
+
# or
|
|
24
|
+
pnpm dev
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Open [http://localhost:5173](http://localhost:5173) with your browser to see the result.
|
|
28
|
+
|
|
29
|
+
You can start editing the page by modifying `src/pages/index.tsx`. The page auto-updates as you edit the file.
|
|
30
|
+
|
|
31
|
+
## Project Structure
|
|
32
|
+
|
|
33
|
+
- `src/pages` - File-based routing for your application.
|
|
34
|
+
- `src/server` - Server-side logic and RPC functions.
|
|
35
|
+
- `src/components` - React components.
|
|
36
|
+
- `helium.config.ts` - HeliumTS configuration.
|
|
37
|
+
|
|
38
|
+
## Learn More
|
|
39
|
+
|
|
40
|
+
To learn more about HeliumTS, take a look at the following resources:
|
|
41
|
+
|
|
42
|
+
- [HeliumTS Documentation](https://heliumts.com/docs) - learn about HeliumTS features and API.
|
|
43
|
+
- [HeliumTS GitHub](https://github.com/heliobentes/heliumts) - check out the source code and contribute.
|
|
44
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import js from '@eslint/js'
|
|
2
|
+
import globals from 'globals'
|
|
3
|
+
import reactHooks from 'eslint-plugin-react-hooks'
|
|
4
|
+
import reactRefresh from 'eslint-plugin-react-refresh'
|
|
5
|
+
import tseslint from 'typescript-eslint'
|
|
6
|
+
import { defineConfig, globalIgnores } from 'eslint/config'
|
|
7
|
+
|
|
8
|
+
export default defineConfig([
|
|
9
|
+
globalIgnores(['dist']),
|
|
10
|
+
{
|
|
11
|
+
files: ['**/*.{ts,tsx}'],
|
|
12
|
+
extends: [
|
|
13
|
+
js.configs.recommended,
|
|
14
|
+
tseslint.configs.recommended,
|
|
15
|
+
reactHooks.configs.flat.recommended,
|
|
16
|
+
reactRefresh.configs.vite,
|
|
17
|
+
],
|
|
18
|
+
languageOptions: {
|
|
19
|
+
ecmaVersion: 2020,
|
|
20
|
+
globals: globals.browser,
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
])
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { HeliumConfig } from "heliumts/server";
|
|
2
|
+
|
|
3
|
+
const config: HeliumConfig = {
|
|
4
|
+
trustProxyDepth: 1, // Trust 1 proxy level (e.g., DigitalOcean, Netlify, etc.)
|
|
5
|
+
rpc: {
|
|
6
|
+
transport: "websocket",
|
|
7
|
+
autoHttpOnMobile: false,
|
|
8
|
+
compression: {
|
|
9
|
+
enabled: true,
|
|
10
|
+
threshold: 1024,
|
|
11
|
+
},
|
|
12
|
+
security: {
|
|
13
|
+
maxConnectionsPerIP: 10,
|
|
14
|
+
maxMessagesPerWindow: 200,
|
|
15
|
+
rateLimitWindowMs: 60000,
|
|
16
|
+
tokenValidityMs: 30000,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
export default config;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/helium.png" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>HeliumTS App</title>
|
|
8
|
+
<link href="/src/styles.css" rel="stylesheet" />
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
<div id="root"></div>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|