feat(cli): add Nitro backend - #1177
AmanVarshney01 wants to merge 2 commits into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThe PR adds experimental Nitro 3 support across CLI selection, configuration validation, native project generation, API and authentication integrations, Docker, Prisma, Vercel, and Cloudflare deployment, generated-build verification, and documentation. ChangesNitro backend support
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 1d03cc6f-9f76-4b1a-9f03-43107ddb6a60
⛔ Files ignored due to path filters (1)
packages/template-generator/src/templates.generated.tsis excluded by!**/*.generated.*
📒 Files selected for processing (59)
apps/cli/src/prompts/backend.tsapps/cli/src/prompts/database-setup.tsapps/cli/src/prompts/server-deploy.tsapps/cli/src/utils/compatibility-rules.tsapps/cli/src/utils/config-validation.tsapps/cli/src/utils/display-config.tsapps/cli/src/utils/requirements.tsapps/cli/test/addons.test.tsapps/cli/test/api.test.tsapps/cli/test/auth.test.tsapps/cli/test/backend-runtime.test.tsapps/cli/test/deployment.test.tsapps/cli/test/generated-builds.test.tsapps/cli/test/nitro.test.tsapps/cli/test/requirements.test.tsapps/web/content/docs/cli/compatibility.mdxapps/web/content/docs/cli/index.mdxapps/web/content/docs/cli/options.mdxapps/web/content/docs/guides/cloudflare-alchemy.mdxapps/web/content/docs/guides/docker.mdxapps/web/content/docs/guides/vercel.mdxapps/web/content/docs/index.mdxapps/web/content/docs/project-structure.mdxapps/web/src/app/(home)/new/_components/utils.tsapps/web/src/lib/constant.tsapps/web/test/stack-builder-compatibility.test.tsopenspec/changes/add-nitro-backend/.openspec.yamlopenspec/changes/add-nitro-backend/design.mdopenspec/changes/add-nitro-backend/proposal.mdopenspec/changes/add-nitro-backend/specs/nitro-backend/spec.mdopenspec/changes/add-nitro-backend/tasks.mdpackages/template-generator/src/generators/alchemy/server.tspackages/template-generator/src/post-process/vercel-config.tspackages/template-generator/src/processors/api-deps.tspackages/template-generator/src/processors/auth-deps.tspackages/template-generator/src/processors/backend-deps.tspackages/template-generator/src/processors/readme-generator.tspackages/template-generator/src/processors/runtime-deps.tspackages/template-generator/src/processors/turbo-generator.tspackages/template-generator/src/processors/workspace-deps.tspackages/template-generator/src/template-handlers/backend.tspackages/template-generator/src/utils/generated-ignore-patterns.tspackages/template-generator/templates/api/orpc/server/src/context.ts.hbspackages/template-generator/templates/api/trpc/server/src/context.ts.hbspackages/template-generator/templates/backend/server/nitro/ai/server/routes/ai.post.ts.hbspackages/template-generator/templates/backend/server/nitro/base/_gitignorepackages/template-generator/templates/backend/server/nitro/base/nitro.config.ts.hbspackages/template-generator/templates/backend/server/nitro/base/package.json.hbspackages/template-generator/templates/backend/server/nitro/base/server/middleware/cors.ts.hbspackages/template-generator/templates/backend/server/nitro/base/server/routes/index.get.ts.hbspackages/template-generator/templates/backend/server/nitro/base/tsconfig.json.hbspackages/template-generator/templates/backend/server/nitro/better-auth/server/routes/api/auth/[...all].ts.hbspackages/template-generator/templates/backend/server/nitro/native-polar/server/routes/polar/success.get.ts.hbspackages/template-generator/templates/backend/server/nitro/orpc/server/routes/api-reference/[...].ts.hbspackages/template-generator/templates/backend/server/nitro/orpc/server/routes/rpc/[...].ts.hbspackages/template-generator/templates/backend/server/nitro/trpc/server/routes/trpc/[...].ts.hbspackages/template-generator/templates/deploy/docker/server/Dockerfile.hbspackages/template-generator/templates/packages/env/src/server.ts.hbspackages/types/src/schemas.ts
|
Cloudflare support is now included in The generated stack builds Nitro's official Verified locally and on a disposable live Cloudflare stage: web, Nitro server, oRPC, Better Auth, CORS, D1 reads/writes, deployed server URL wiring, and destroy. The full CLI suite remains clean at 709 passed, 38 skipped, 0 failed. All review threads are resolved. |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 44f250e2-2976-4fa0-a616-13593154aadf
⛔ Files ignored due to path filters (1)
packages/template-generator/src/templates.generated.tsis excluded by!**/*.generated.*
📒 Files selected for processing (29)
apps/cli/src/prompts/runtime.tsapps/cli/src/utils/compatibility-rules.tsapps/cli/src/utils/config-validation.tsapps/cli/test/backend-runtime.test.tsapps/cli/test/generated-builds.test.tsapps/cli/test/matrix/oracle.tsapps/cli/test/nitro.test.tsapps/web/content/docs/cli/compatibility.mdxapps/web/content/docs/guides/cloudflare-alchemy.mdxapps/web/content/docs/project-structure.mdxapps/web/src/app/(home)/new/_components/utils.tsapps/web/test/stack-builder-compatibility.test.tsopenspec/changes/add-nitro-backend/design.mdopenspec/changes/add-nitro-backend/proposal.mdopenspec/changes/add-nitro-backend/specs/nitro-backend/spec.mdopenspec/changes/add-nitro-backend/tasks.mdpackages/template-generator/src/generators/alchemy/env.tspackages/template-generator/src/generators/alchemy/render.tspackages/template-generator/src/generators/alchemy/server.tspackages/template-generator/src/processors/env-vars.tspackages/template-generator/src/processors/runtime-deps.tspackages/template-generator/templates/api/orpc/server/src/context.ts.hbspackages/template-generator/templates/api/trpc/server/src/context.ts.hbspackages/template-generator/templates/backend/server/nitro/base/_gitignorepackages/template-generator/templates/backend/server/nitro/base/nitro.config.ts.hbspackages/template-generator/templates/backend/server/nitro/base/tsconfig.json.hbspackages/template-generator/templates/backend/server/nitro/better-auth/server/routes/api/auth/[...all].ts.hbspackages/template-generator/templates/extras/env.d.ts.hbspackages/template-generator/templates/packages/env/src/server.ts.hbs
🚧 Files skipped from review as they are similar to previous changes (12)
- packages/template-generator/templates/backend/server/nitro/base/tsconfig.json.hbs
- packages/template-generator/templates/backend/server/nitro/base/_gitignore
- packages/template-generator/src/processors/runtime-deps.ts
- apps/web/content/docs/project-structure.mdx
- apps/web/test/stack-builder-compatibility.test.ts
- apps/web/content/docs/cli/compatibility.mdx
- apps/cli/test/nitro.test.ts
- packages/template-generator/templates/api/orpc/server/src/context.ts.hbs
- openspec/changes/add-nitro-backend/proposal.md
- packages/template-generator/templates/api/trpc/server/src/context.ts.hbs
- apps/cli/test/generated-builds.test.ts
- openspec/changes/add-nitro-backend/tasks.md
| "main: Output.map(build.outdir, (outdir) => `${outdir}/server/index.mjs`),", | ||
| ); | ||
| writer.writeLine("bundle: false,"); | ||
| writeObject( | ||
| writer, | ||
| "assets: {", | ||
| () => { | ||
| writer.writeLine('directory: "../../apps/server/.output/public",'); | ||
| }, | ||
| "},", |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ast-grep outline packages/template-generator/src/generators/alchemy/server.ts --items all
rg -n -C 4 'Command\.Build|build\.outdir|Output\.map|assets:|directory:' \
packages/template-generator/src/generators/alchemy/server.ts \
packages/template-generator/src \
apps/cli/test
fd -a 'nitro.config.ts.hbs' packages/template-generator/templates -x sed -n '1,180p' {}Repository: AmanVarshney01/create-better-t-stack
Length of output: 14851
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- server generator ---'
cat -n packages/template-generator/src/generators/alchemy/server.ts | sed -n '1,115p'
printf '%s\n' '--- Alchemy dependency and API references ---'
rg -n -C 5 'Command\.Build|interface.*Build|type.*Build|outdir|assets:\s*\{|directory:' \
package.json packages/*/package.json pnpm-lock.yaml packages apps \
-g '*.ts' -g '*.tsx' -g '*.json' -g '*.yaml' -g '*.yml' -g '*.md' \
| head -n 500
printf '%s\n' '--- generated fixtures and deployment documentation ---'
rg -n -C 8 'server-build|\.output/public|Cloudflare\.Worker|Command\.Build' . \
-g '!packages/template-generator/src/templates.generated.ts' \
-g '!node_modules' | head -n 500Repository: AmanVarshney01/create-better-t-stack
Length of output: 36990
🌐 Web query:
Alchemy Effect Command.Build outdir Cloudflare.Worker assets directory API
💡 Result:
In the Alchemy framework, Command.Build is a resource that executes a shell command to generate an output directory (outdir), which can then be consumed by downstream resources like a Cloudflare Worker for static asset deployment [1][2]. When using Command.Build, you define the build process and specify the resulting directory as follows: const build = yield* Command.Build("build-name", { command: "npm run build", cwd: "./frontend", outdir: "dist", // The directory produced by the build command }); Downstream, a Cloudflare Worker resource can reference this outdir to serve static assets. In the Alchemy Cloudflare provider, this is typically handled via the assets configuration [3][4]. For example, when creating a Cloudflare Worker, you can map the build output to the assets directory: export default Cloudflare.Worker("Worker", { assets: { directory: build.outdir, // Consumes the output from the Command.Build resource run_worker_first: false, }, }); Alchemy effectively bridges the gap between build-time artifacts and deployment-time configuration by tracking the outdir in state and verifying its existence after the command execution [5][2]. This ensures that your Cloudflare Worker is always deploying the latest version of your assets produced by the specified build process [6][2]. For more complex requirements, Alchemy also provides a higher-level abstraction, Cloudflare.Website.StaticSite, which combines a build command and static asset deployment into a single resource [6]. It is important to note that Cloudflare's underlying asset layer handles the actual file serving [7][8]. The directory specified (e.g.,./dist or./public) is what gets uploaded to Cloudflare's infrastructure during deployment [7][9]. You can further configure behavior such as 404 handling or specific routing patterns (run_worker_first) within the assets object [3][7][10].
Citations:
- 1: https://alchemy.run/command/
- 2: https://alchemy.run/providers/command/build/
- 3: https://alchemy.run/cloudflare/compute/workers/
- 4: https://alchemy.run/providers/cloudflare/worker
- 5: https://alchemy.run/command/memoization/
- 6: https://alchemy.run/cloudflare/frontend/static-site
- 7: https://developers.cloudflare.com/workers/static-assets/
- 8: https://developers.cloudflare.com/workers/static-assets/index.md
- 9: https://developers.cloudflare.com/workers/static-assets/binding/
- 10: https://developers.cloudflare.com/workers/static-assets/routing/worker-script/index.md
🏁 Script executed:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
from urllib.request import Request, urlopen
urls = [
"https://alchemy.run/providers/command/build/",
"https://alchemy.run/cloudflare/compute/workers/",
]
needles = ("outdir", "assets", "directory", "Command.Build")
for url in urls:
print(f"--- {url} ---")
request = Request(url, headers={"User-Agent": "Mozilla/5.0"})
try:
text = urlopen(request, timeout=20).read().decode("utf-8", "replace")
except Exception as error:
print(f"fetch error: {error}")
continue
lower = text.lower()
for needle in needles:
start = 0
found = 0
while found < 3:
index = lower.find(needle.lower(), start)
if index < 0:
break
print(text[max(0, index - 180):index + 300].replace("\n", " ")[:500])
start = index + len(needle)
found += 1
PY
printf '%s\n' '--- path relationship in the generator and tests ---'
python3 - <<'PY'
from pathlib import Path
source = Path("packages/template-generator/src/generators/alchemy/server.ts").read_text()
test = Path("apps/cli/test/nitro.test.ts").read_text()
required_source = [
'outdir: ".output"',
'main: Output.map(build.outdir, (outdir) => `${outdir}/server/index.mjs`)',
'directory: "../../apps/server/.output/public"',
]
required_test = [
'outdir: ".output"',
'`${outdir}/server/index.mjs`',
'directory: "../../apps/server/.output/public"',
]
for label, text, required in [
("generator", source, required_source),
("test", test, required_test),
]:
print(label)
for item in required:
print(f"{item!r}: {item in text}")
PYRepository: AmanVarshney01/create-better-t-stack
Length of output: 925
🏁 Script executed:
#!/bin/bash
set -euo pipefail
for url in \
"https://alchemy.run/providers/command/build/" \
"https://alchemy.run/cloudflare/compute/workers/" \
"https://raw.githubusercontent.com/alchemy-run/alchemy/main/packages/cloudflare/src/worker.ts"
do
printf '%s\n' "--- $url ---"
curl -k -L --max-time 20 -sS "$url" \
| tr '\n' ' ' \
| grep -oE '.{0,220}(Command\.Build|build\.outdir|assets|directory|outdir).{0,320}' \
| head -n 12 || true
doneRepository: AmanVarshney01/create-better-t-stack
Length of output: 12689
Derive the asset directory from build.outdir.
Set directory to Output.map(build.outdir, (outdir) => ${outdir}/public). This keeps static assets and main within the same Command.Build artifact.
Summary
.outputartifactscloudflare_modulepreset and Alchemy's publicCommand.Build+ prebuiltCloudflare.WorkerAPIsVerification
bun run checkbun run buildSummary by CodeRabbit
New Features
Bug Fixes
Documentation