@nimbuslab/cli 0.16.3 → 0.16.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 +41 -75
- package/dist/index.js +72 -10
- package/package.json +12 -2
- package/.github/workflows/publish.yml +0 -67
- package/CLAUDE.md +0 -106
- package/MIGRATION-ROADMAP.md +0 -201
- package/bun.lock +0 -36
- package/docs/CI-CD.md +0 -181
- package/docs/analyze.md +0 -148
- package/docs/create.md +0 -219
- package/docs/migrate.md +0 -177
- package/docs/package.md +0 -229
- package/docs/upgrade.md +0 -152
- package/src/commands/analyze.ts +0 -210
- package/src/commands/create.ts +0 -1323
- package/src/commands/lola.ts +0 -1026
- package/src/commands/update.ts +0 -267
- package/src/commands/upgrade.ts +0 -251
- package/src/index.ts +0 -161
- package/tsconfig.json +0 -29
package/README.md
CHANGED
|
@@ -1,117 +1,83 @@
|
|
|
1
1
|
# @nimbuslab/cli
|
|
2
2
|
|
|
3
|
-
CLI
|
|
3
|
+
CLI para criar projetos com a stack moderna da nimbuslab.
|
|
4
|
+
|
|
5
|
+
## Instalacao
|
|
4
6
|
|
|
5
7
|
```bash
|
|
6
8
|
bun add -g @nimbuslab/cli
|
|
7
9
|
```
|
|
8
10
|
|
|
9
|
-
---
|
|
10
|
-
|
|
11
11
|
## Comandos
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
---
|
|
13
|
+
```bash
|
|
14
|
+
nimbus create # Criar novo projeto (interativo)
|
|
15
|
+
nimbus analyze # Analisar stack do projeto atual
|
|
16
|
+
nimbus upgrade # Planejar upgrades de dependencias
|
|
17
|
+
nimbus update # Atualizar o CLI
|
|
18
|
+
nimbus help # Ajuda
|
|
19
|
+
```
|
|
21
20
|
|
|
22
|
-
##
|
|
21
|
+
## Templates
|
|
23
22
|
|
|
24
|
-
###
|
|
23
|
+
### Landing Page
|
|
25
24
|
|
|
26
25
|
```bash
|
|
27
26
|
nimbus create meu-site --landing
|
|
28
|
-
cd meu-site
|
|
29
|
-
bun dev
|
|
30
27
|
```
|
|
31
28
|
|
|
32
|
-
|
|
29
|
+
Stack: Next.js 16 + React 19 + Tailwind CSS 4 + shadcn/ui
|
|
30
|
+
|
|
31
|
+
### Web App
|
|
33
32
|
|
|
34
33
|
```bash
|
|
35
34
|
nimbus create meu-app --app
|
|
36
|
-
cd meu-app
|
|
37
|
-
bun setup
|
|
38
|
-
bun dev
|
|
39
35
|
```
|
|
40
36
|
|
|
41
|
-
|
|
37
|
+
Stack: Landing + Better Auth + Drizzle ORM + Docker
|
|
38
|
+
|
|
39
|
+
### Monorepo
|
|
42
40
|
|
|
43
41
|
```bash
|
|
44
|
-
nimbus
|
|
45
|
-
nimbus upgrade --plan
|
|
42
|
+
nimbus create meu-projeto --turborepo
|
|
46
43
|
```
|
|
47
44
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
## Templates
|
|
51
|
-
|
|
52
|
-
| Template | Descricao | Docs |
|
|
53
|
-
|----------|-----------|------|
|
|
54
|
-
| `--landing` | Next.js 16 + Tailwind 4 + shadcn/ui | [docs/create.md#landing](./docs/create.md#landing-page---landing) |
|
|
55
|
-
| `--app` | Landing + Better Auth + Drizzle | [docs/create.md#app](./docs/create.md#web-app---app) |
|
|
56
|
-
| `--turborepo` | Monorepo com apps e packages | [docs/create.md#turborepo](./docs/create.md#turborepo---turborepo) |
|
|
57
|
-
| `--package` | Pacote npm com tsup + CI/CD | [docs/package.md](./docs/package.md) |
|
|
58
|
-
|
|
59
|
-
**Repos Open Source:**
|
|
60
|
-
- [create-next-landing](https://github.com/nimbuslab/create-next-landing)
|
|
61
|
-
- [create-next-app](https://github.com/nimbuslab/create-next-app)
|
|
62
|
-
- [create-turborepo](https://github.com/nimbuslab/create-turborepo)
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Stack Alvo
|
|
45
|
+
Stack: Turborepo + apps/packages compartilhados
|
|
67
46
|
|
|
68
|
-
|
|
69
|
-
|-----------|------------|
|
|
70
|
-
| Framework | Next.js 16+ |
|
|
71
|
-
| Runtime | React 19+ |
|
|
72
|
-
| Styling | Tailwind CSS 4+ |
|
|
73
|
-
| Components | shadcn/ui |
|
|
74
|
-
| Package Manager | Bun |
|
|
75
|
-
| Auth | Better Auth |
|
|
76
|
-
| Database | Drizzle ORM |
|
|
77
|
-
| Monorepo | Turborepo |
|
|
47
|
+
## Analyze e Upgrade
|
|
78
48
|
|
|
79
|
-
|
|
49
|
+
```bash
|
|
50
|
+
# Analisar projeto existente
|
|
51
|
+
nimbus analyze ./meu-projeto
|
|
52
|
+
nimbus analyze --json
|
|
80
53
|
|
|
81
|
-
|
|
54
|
+
# Planejar upgrades
|
|
55
|
+
nimbus upgrade --plan
|
|
56
|
+
nimbus upgrade tailwind
|
|
57
|
+
nimbus upgrade next
|
|
58
|
+
```
|
|
82
59
|
|
|
83
|
-
|
|
84
|
-
|---------|----------|
|
|
85
|
-
| [docs/create.md](./docs/create.md) | Templates, opcoes, fluxo interativo |
|
|
86
|
-
| [docs/package.md](./docs/package.md) | Criar pacotes npm |
|
|
87
|
-
| [docs/analyze.md](./docs/analyze.md) | Deteccao de stack, recomendacoes |
|
|
88
|
-
| [docs/upgrade.md](./docs/upgrade.md) | Breaking changes, codemods |
|
|
89
|
-
| [docs/migrate.md](./docs/migrate.md) | Strangler Fig, estrategias |
|
|
90
|
-
| [MIGRATION-ROADMAP.md](./MIGRATION-ROADMAP.md) | Roadmap de migracao |
|
|
60
|
+
## Opcoes
|
|
91
61
|
|
|
92
|
-
|
|
62
|
+
| Flag | Descricao |
|
|
63
|
+
|------|-----------|
|
|
64
|
+
| `-y, --yes` | Aceitar padroes |
|
|
65
|
+
| `--no-git` | Nao inicializar Git |
|
|
66
|
+
| `--no-install` | Nao instalar dependencias |
|
|
93
67
|
|
|
94
68
|
## Requisitos
|
|
95
69
|
|
|
96
|
-
- [Bun](https://bun.sh)
|
|
97
|
-
- [Git](https://git-scm.com) - Controle de versao
|
|
70
|
+
- [Bun](https://bun.sh) >= 1.0
|
|
98
71
|
|
|
99
72
|
```bash
|
|
100
73
|
curl -fsSL https://bun.sh/install | bash
|
|
101
74
|
```
|
|
102
75
|
|
|
103
|
-
|
|
76
|
+
## Templates Open Source
|
|
104
77
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
gh repo clone nimbuslab/cli
|
|
109
|
-
cd cli
|
|
110
|
-
bun install
|
|
111
|
-
bun run dev
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
---
|
|
78
|
+
- [create-next-landing](https://github.com/nimbuslab/create-next-landing)
|
|
79
|
+
- [create-next-app](https://github.com/nimbuslab/create-next-app)
|
|
80
|
+
- [create-turborepo](https://github.com/nimbuslab/create-turborepo)
|
|
115
81
|
|
|
116
82
|
## Licenca
|
|
117
83
|
|
package/dist/index.js
CHANGED
|
@@ -150,18 +150,28 @@ var require_src = __commonJS((exports, module) => {
|
|
|
150
150
|
var require_package = __commonJS((exports, module) => {
|
|
151
151
|
module.exports = {
|
|
152
152
|
name: "@nimbuslab/cli",
|
|
153
|
-
version: "0.16.
|
|
153
|
+
version: "0.16.4",
|
|
154
154
|
description: "CLI para criar projetos nimbuslab",
|
|
155
155
|
type: "module",
|
|
156
156
|
bin: {
|
|
157
157
|
nimbus: "./dist/index.js"
|
|
158
158
|
},
|
|
159
|
+
files: [
|
|
160
|
+
"dist"
|
|
161
|
+
],
|
|
159
162
|
scripts: {
|
|
160
163
|
dev: "bun run src/index.ts",
|
|
161
164
|
build: "bun build src/index.ts --outdir dist --target bun",
|
|
162
165
|
typecheck: "tsc --noEmit"
|
|
163
166
|
},
|
|
164
|
-
keywords: [
|
|
167
|
+
keywords: [
|
|
168
|
+
"nimbuslab",
|
|
169
|
+
"cli",
|
|
170
|
+
"nextjs",
|
|
171
|
+
"fast",
|
|
172
|
+
"landing-page",
|
|
173
|
+
"saas"
|
|
174
|
+
],
|
|
165
175
|
author: {
|
|
166
176
|
name: "nimbuslab",
|
|
167
177
|
email: "contato@nimbuslab.com.br",
|
|
@@ -2360,9 +2370,55 @@ function printUpgradePlan(name, plan) {
|
|
|
2360
2370
|
var import_picocolors6 = __toESM(require_picocolors(), 1);
|
|
2361
2371
|
import { execSync, spawnSync } from "child_process";
|
|
2362
2372
|
var PACKAGE_NAME = "@nimbuslab/cli";
|
|
2373
|
+
function hasBunInstall() {
|
|
2374
|
+
try {
|
|
2375
|
+
const result = spawnSync("bun", ["pm", "ls", "-g"], {
|
|
2376
|
+
encoding: "utf-8",
|
|
2377
|
+
shell: true,
|
|
2378
|
+
timeout: 5000
|
|
2379
|
+
});
|
|
2380
|
+
return !!(result.stdout && result.stdout.includes(PACKAGE_NAME));
|
|
2381
|
+
} catch {
|
|
2382
|
+
return false;
|
|
2383
|
+
}
|
|
2384
|
+
}
|
|
2385
|
+
function hasNpmInstall() {
|
|
2386
|
+
try {
|
|
2387
|
+
const result = spawnSync("npm", ["ls", "-g", PACKAGE_NAME, "--json"], {
|
|
2388
|
+
encoding: "utf-8",
|
|
2389
|
+
shell: true,
|
|
2390
|
+
timeout: 5000
|
|
2391
|
+
});
|
|
2392
|
+
if (result.stdout) {
|
|
2393
|
+
const data = JSON.parse(result.stdout);
|
|
2394
|
+
return !!data.dependencies?.[PACKAGE_NAME];
|
|
2395
|
+
}
|
|
2396
|
+
} catch {}
|
|
2397
|
+
return false;
|
|
2398
|
+
}
|
|
2399
|
+
function cleanupDuplicateInstalls() {
|
|
2400
|
+
const hasNpm = hasNpmInstall();
|
|
2401
|
+
const hasBun = hasBunInstall();
|
|
2402
|
+
if (hasNpm && hasBun) {
|
|
2403
|
+
try {
|
|
2404
|
+
execSync("bun remove -g @nimbuslab/cli", { stdio: "pipe", encoding: "utf-8" });
|
|
2405
|
+
return {
|
|
2406
|
+
cleaned: true,
|
|
2407
|
+
message: "Instalacao duplicada removida do bun (usando npm)"
|
|
2408
|
+
};
|
|
2409
|
+
} catch {
|
|
2410
|
+
return {
|
|
2411
|
+
cleaned: false,
|
|
2412
|
+
message: "Falha ao remover instalacao duplicada do bun"
|
|
2413
|
+
};
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
return { cleaned: false, message: "" };
|
|
2417
|
+
}
|
|
2363
2418
|
function isUsingFnm() {
|
|
2364
2419
|
const fnmDir = process.env.FNM_DIR || process.env.FNM_MULTISHELL_PATH;
|
|
2365
|
-
const
|
|
2420
|
+
const checkCmd = process.platform === "win32" ? "where" : "which";
|
|
2421
|
+
const whichNode = spawnSync(checkCmd, ["node"], { encoding: "utf-8", shell: true });
|
|
2366
2422
|
return !!(fnmDir || whichNode.stdout && whichNode.stdout.includes("fnm"));
|
|
2367
2423
|
}
|
|
2368
2424
|
async function getAvailableVersions() {
|
|
@@ -2478,6 +2534,13 @@ async function update(args) {
|
|
|
2478
2534
|
const isSpecificVersion = flag && flag !== "latest" && !flag.startsWith("-");
|
|
2479
2535
|
Ie(import_picocolors6.default.cyan(`Atualizando ${PACKAGE_NAME}`));
|
|
2480
2536
|
const spinner = Y2();
|
|
2537
|
+
spinner.start("Verificando instalacoes...");
|
|
2538
|
+
const cleanup = cleanupDuplicateInstalls();
|
|
2539
|
+
if (cleanup.cleaned) {
|
|
2540
|
+
spinner.stop(import_picocolors6.default.yellow(cleanup.message));
|
|
2541
|
+
} else {
|
|
2542
|
+
spinner.stop("OK");
|
|
2543
|
+
}
|
|
2481
2544
|
spinner.start("Detectando package manager...");
|
|
2482
2545
|
const detectedPm = detectPackageManager2();
|
|
2483
2546
|
const pm = detectedPm === "unknown" ? "npm" : detectedPm;
|
|
@@ -2564,18 +2627,19 @@ var LOLA_MEMORY_URL = "https://lola.nimbuslab.com.br/sse";
|
|
|
2564
2627
|
var LOLA_MEMORY_NAME = "lola-memory";
|
|
2565
2628
|
var GEMINI_DIR = join3(HOME, ".gemini");
|
|
2566
2629
|
var GEMINI_SETTINGS = join3(GEMINI_DIR, "GEMINI.md");
|
|
2630
|
+
var CHECK_CMD = process.platform === "win32" ? "where" : "which";
|
|
2567
2631
|
function hasClaudeCLI() {
|
|
2568
|
-
const result = Bun.spawnSync([
|
|
2632
|
+
const result = Bun.spawnSync([CHECK_CMD, "claude"], { stdout: "pipe", stderr: "pipe" });
|
|
2569
2633
|
return result.exitCode === 0;
|
|
2570
2634
|
}
|
|
2571
2635
|
function hasGeminiCLI() {
|
|
2572
|
-
const result = Bun.spawnSync([
|
|
2636
|
+
const result = Bun.spawnSync([CHECK_CMD, "gemini"], { stdout: "pipe", stderr: "pipe" });
|
|
2573
2637
|
return result.exitCode === 0;
|
|
2574
2638
|
}
|
|
2575
2639
|
async function installLolaMemoryMCP() {
|
|
2576
2640
|
console.log();
|
|
2577
2641
|
console.log(import_picocolors7.default.cyan(" Configurando lola-memory MCP..."));
|
|
2578
|
-
const claudeCheck = Bun.spawnSync([
|
|
2642
|
+
const claudeCheck = Bun.spawnSync([CHECK_CMD, "claude"], { stdout: "pipe", stderr: "pipe" });
|
|
2579
2643
|
if (claudeCheck.exitCode !== 0) {
|
|
2580
2644
|
console.log(import_picocolors7.default.yellow(" Claude CLI nao encontrado, pulando MCP"));
|
|
2581
2645
|
console.log(import_picocolors7.default.dim(" Instale o Claude CLI e rode 'nimbus lola install' novamente"));
|
|
@@ -2592,8 +2656,6 @@ async function installLolaMemoryMCP() {
|
|
|
2592
2656
|
"claude",
|
|
2593
2657
|
"mcp",
|
|
2594
2658
|
"add",
|
|
2595
|
-
"-t",
|
|
2596
|
-
"sse",
|
|
2597
2659
|
"-s",
|
|
2598
2660
|
"user",
|
|
2599
2661
|
LOLA_MEMORY_NAME,
|
|
@@ -2607,7 +2669,7 @@ async function installLolaMemoryMCP() {
|
|
|
2607
2669
|
});
|
|
2608
2670
|
if (result.exitCode !== 0) {
|
|
2609
2671
|
console.log(import_picocolors7.default.yellow(" Erro ao adicionar MCP, pode ser adicionado manualmente:"));
|
|
2610
|
-
console.log(import_picocolors7.default.dim(` claude mcp add -
|
|
2672
|
+
console.log(import_picocolors7.default.dim(` claude mcp add -s user ${LOLA_MEMORY_NAME} -- bunx mcp-remote ${LOLA_MEMORY_URL}`));
|
|
2611
2673
|
return;
|
|
2612
2674
|
}
|
|
2613
2675
|
console.log(import_picocolors7.default.green(" MCP lola-memory instalado!"));
|
|
@@ -2765,7 +2827,7 @@ async function suggestImprovement(message) {
|
|
|
2765
2827
|
console.log(import_picocolors7.default.dim(' Uso: nimbus lola suggest "sua sugestao aqui"'));
|
|
2766
2828
|
process.exit(1);
|
|
2767
2829
|
}
|
|
2768
|
-
const ghCheck = Bun.spawnSync(["
|
|
2830
|
+
const ghCheck = Bun.spawnSync([CHECK_CMD, "gh"], { stderr: "pipe" });
|
|
2769
2831
|
if (ghCheck.exitCode !== 0) {
|
|
2770
2832
|
console.log(import_picocolors7.default.red(" Erro: GitHub CLI (gh) nao encontrado"));
|
|
2771
2833
|
console.log(import_picocolors7.default.dim(" Instale: https://cli.github.com"));
|
package/package.json
CHANGED
|
@@ -1,17 +1,27 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nimbuslab/cli",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.5",
|
|
4
4
|
"description": "CLI para criar projetos nimbuslab",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"nimbus": "./dist/index.js"
|
|
8
8
|
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist"
|
|
11
|
+
],
|
|
9
12
|
"scripts": {
|
|
10
13
|
"dev": "bun run src/index.ts",
|
|
11
14
|
"build": "bun build src/index.ts --outdir dist --target bun",
|
|
12
15
|
"typecheck": "tsc --noEmit"
|
|
13
16
|
},
|
|
14
|
-
"keywords": [
|
|
17
|
+
"keywords": [
|
|
18
|
+
"nimbuslab",
|
|
19
|
+
"cli",
|
|
20
|
+
"nextjs",
|
|
21
|
+
"fast",
|
|
22
|
+
"landing-page",
|
|
23
|
+
"saas"
|
|
24
|
+
],
|
|
15
25
|
"author": {
|
|
16
26
|
"name": "nimbuslab",
|
|
17
27
|
"email": "contato@nimbuslab.com.br",
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
name: Publish to npm
|
|
2
|
-
|
|
3
|
-
on:
|
|
4
|
-
push:
|
|
5
|
-
branches:
|
|
6
|
-
- main
|
|
7
|
-
|
|
8
|
-
jobs:
|
|
9
|
-
publish:
|
|
10
|
-
runs-on: ubuntu-latest
|
|
11
|
-
permissions:
|
|
12
|
-
contents: read
|
|
13
|
-
id-token: write
|
|
14
|
-
|
|
15
|
-
steps:
|
|
16
|
-
- name: Checkout
|
|
17
|
-
uses: actions/checkout@v4
|
|
18
|
-
|
|
19
|
-
- name: Check if version changed
|
|
20
|
-
id: version_check
|
|
21
|
-
run: |
|
|
22
|
-
LOCAL_VERSION=$(node -p "require('./package.json').version")
|
|
23
|
-
NPM_VERSION=$(npm view @nimbuslab/cli version 2>/dev/null || echo "0.0.0")
|
|
24
|
-
echo "local=$LOCAL_VERSION" >> $GITHUB_OUTPUT
|
|
25
|
-
echo "npm=$NPM_VERSION" >> $GITHUB_OUTPUT
|
|
26
|
-
if [ "$LOCAL_VERSION" = "$NPM_VERSION" ]; then
|
|
27
|
-
echo "changed=false" >> $GITHUB_OUTPUT
|
|
28
|
-
echo "Versao $LOCAL_VERSION ja existe no npm. Pulando publish."
|
|
29
|
-
else
|
|
30
|
-
echo "changed=true" >> $GITHUB_OUTPUT
|
|
31
|
-
echo "Nova versao detectada: $NPM_VERSION -> $LOCAL_VERSION"
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
- name: Setup Bun
|
|
35
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
36
|
-
uses: oven-sh/setup-bun@v2
|
|
37
|
-
with:
|
|
38
|
-
bun-version: latest
|
|
39
|
-
|
|
40
|
-
- name: Setup Node (for npm publish)
|
|
41
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
42
|
-
uses: actions/setup-node@v4
|
|
43
|
-
with:
|
|
44
|
-
node-version: "24"
|
|
45
|
-
registry-url: "https://registry.npmjs.org"
|
|
46
|
-
|
|
47
|
-
- name: Install dependencies
|
|
48
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
49
|
-
run: bun install
|
|
50
|
-
|
|
51
|
-
- name: Typecheck
|
|
52
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
53
|
-
run: bun run typecheck
|
|
54
|
-
|
|
55
|
-
- name: Build
|
|
56
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
57
|
-
run: bun run build
|
|
58
|
-
|
|
59
|
-
- name: Publish to npm
|
|
60
|
-
if: steps.version_check.outputs.changed == 'true'
|
|
61
|
-
run: npm publish --access public
|
|
62
|
-
env:
|
|
63
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
64
|
-
|
|
65
|
-
- name: Skip message
|
|
66
|
-
if: steps.version_check.outputs.changed == 'false'
|
|
67
|
-
run: echo "Publish pulado - versao ${{ steps.version_check.outputs.local }} ja existe no npm"
|
package/CLAUDE.md
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
Default to using Bun instead of Node.js.
|
|
3
|
-
|
|
4
|
-
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
|
|
5
|
-
- Use `bun test` instead of `jest` or `vitest`
|
|
6
|
-
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
|
|
7
|
-
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
|
|
8
|
-
- Use `bun run <script>` instead of `npm run <script>` or `yarn run <script>` or `pnpm run <script>`
|
|
9
|
-
- Use `bunx <package> <command>` instead of `npx <package> <command>`
|
|
10
|
-
- Bun automatically loads .env, so don't use dotenv.
|
|
11
|
-
|
|
12
|
-
## APIs
|
|
13
|
-
|
|
14
|
-
- `Bun.serve()` supports WebSockets, HTTPS, and routes. Don't use `express`.
|
|
15
|
-
- `bun:sqlite` for SQLite. Don't use `better-sqlite3`.
|
|
16
|
-
- `Bun.redis` for Redis. Don't use `ioredis`.
|
|
17
|
-
- `Bun.sql` for Postgres. Don't use `pg` or `postgres.js`.
|
|
18
|
-
- `WebSocket` is built-in. Don't use `ws`.
|
|
19
|
-
- Prefer `Bun.file` over `node:fs`'s readFile/writeFile
|
|
20
|
-
- Bun.$`ls` instead of execa.
|
|
21
|
-
|
|
22
|
-
## Testing
|
|
23
|
-
|
|
24
|
-
Use `bun test` to run tests.
|
|
25
|
-
|
|
26
|
-
```ts#index.test.ts
|
|
27
|
-
import { test, expect } from "bun:test";
|
|
28
|
-
|
|
29
|
-
test("hello world", () => {
|
|
30
|
-
expect(1).toBe(1);
|
|
31
|
-
});
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Frontend
|
|
35
|
-
|
|
36
|
-
Use HTML imports with `Bun.serve()`. Don't use `vite`. HTML imports fully support React, CSS, Tailwind.
|
|
37
|
-
|
|
38
|
-
Server:
|
|
39
|
-
|
|
40
|
-
```ts#index.ts
|
|
41
|
-
import index from "./index.html"
|
|
42
|
-
|
|
43
|
-
Bun.serve({
|
|
44
|
-
routes: {
|
|
45
|
-
"/": index,
|
|
46
|
-
"/api/users/:id": {
|
|
47
|
-
GET: (req) => {
|
|
48
|
-
return new Response(JSON.stringify({ id: req.params.id }));
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
// optional websocket support
|
|
53
|
-
websocket: {
|
|
54
|
-
open: (ws) => {
|
|
55
|
-
ws.send("Hello, world!");
|
|
56
|
-
},
|
|
57
|
-
message: (ws, message) => {
|
|
58
|
-
ws.send(message);
|
|
59
|
-
},
|
|
60
|
-
close: (ws) => {
|
|
61
|
-
// handle close
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
development: {
|
|
65
|
-
hmr: true,
|
|
66
|
-
console: true,
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
HTML files can import .tsx, .jsx or .js files directly and Bun's bundler will transpile & bundle automatically. `<link>` tags can point to stylesheets and Bun's CSS bundler will bundle.
|
|
72
|
-
|
|
73
|
-
```html#index.html
|
|
74
|
-
<html>
|
|
75
|
-
<body>
|
|
76
|
-
<h1>Hello, world!</h1>
|
|
77
|
-
<script type="module" src="./frontend.tsx"></script>
|
|
78
|
-
</body>
|
|
79
|
-
</html>
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
With the following `frontend.tsx`:
|
|
83
|
-
|
|
84
|
-
```tsx#frontend.tsx
|
|
85
|
-
import React from "react";
|
|
86
|
-
import { createRoot } from "react-dom/client";
|
|
87
|
-
|
|
88
|
-
// import .css files directly and it works
|
|
89
|
-
import './index.css';
|
|
90
|
-
|
|
91
|
-
const root = createRoot(document.body);
|
|
92
|
-
|
|
93
|
-
export default function Frontend() {
|
|
94
|
-
return <h1>Hello, world!</h1>;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
root.render(<Frontend />);
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Then, run index.ts
|
|
101
|
-
|
|
102
|
-
```sh
|
|
103
|
-
bun --hot ./index.ts
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
For more information, read the Bun API docs in `node_modules/bun-types/docs/**.mdx`.
|