1# @alchemy.run/frontend-frameworks/solidstart
2
3Adapter-free SolidStart integration: programmatic build and dev for SolidStart
4projects, with the deploy platform passed in as a **deploy target** value. AWS
5Lambda is the built-in target (`@alchemy.run/frontend-frameworks/solidstart/aws`);
6the framework half of this package contains no AWS code at all.
7
8## Architecture: framework half × target half
9
10| Module | Role |
11| ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
12| `@alchemy.run/frontend-frameworks/solidstart` (`SolidStart.ts`, `index.ts`, `UserConfig.ts`) | **Framework half.** Drives the PROJECT's own Vite install (`createBuilder(...).buildApp()` for build, `createServer()` for dev), appends the SolidStart nitro plugin carrying the target's preset, and maps nitro's `.output` onto framework-core's `BuildOutput`. Target-agnostic — zero AWS imports. |
13| `@alchemy.run/frontend-frameworks/solidstart/aws` (`aws.ts`) | **Target half.** The AWS Lambda `SolidStartTarget`: nitro's `aws-lambda` preset, `awsLambda.streaming`, the Node bundle settings, and the wholesale `build` hook that runs the build in a disposable child process. |
14
15Background on why the integration is shaped this way:
16
17- **SolidStart 2 is expressed entirely as Vite plugins.** `solidStart()` from
18 `@solidjs/start/config` declares the `client` and `ssr` environments and a
19 `builder.buildApp` that builds both; `@solidjs/vite-plugin-nitro-2` declares
20 a second `buildApp` that additionally runs nitro over the emitted SSR
21 bundle. There is no adapter file and no framework CLI to drive.
22- **`vite.build()` is not enough.** Vite's legacy `build()` builds one
23 environment, so it would silently produce the client bundle and no server.
24 The integration uses `createBuilder(...).buildApp()`, the path `vite build`
25 itself takes.
26- **The deploy target owns the nitro preset, and the plugin is the only seam.**
27 `nitroV2Plugin` always passes a `preset` down to nitro (its own default is
28 `node-server`), so neither `NITRO_PRESET` nor a `nitro.config.ts` can
29 override it. The integration therefore constructs the plugin itself and
30 appends it through vite's inline config: inline plugins are concatenated
31 after the config file's, and vite merges plugin `config()` results in order,
32 so the appended instance's `buildApp` gets the last word. A project that
33 registers `nitroV2Plugin` in its own vite config would have its nitro
34 options silently dropped, so that **fails the build with an actionable
35 error** (`hasForeignNitroPlugin` / `pluginConflictMessage`) — nitro options
36 belong on the integration's `nitro` option, which forwards them.
37- **The `aws-lambda` output needs no finishing pass.** Nitro emits
38 `.output/server/index.mjs` exporting a `handler`, its own
39 `package.json` (`type: "module"`), and copied externals under
40 `.output/server/node_modules` — a complete Node deployment unit. Client
41 assets and prerendered pages land in `.output/public`.
42- **Builds run in a child process.** `solidStart()` scans the route directory
43 from `process.cwd()` at config-load time and user plugins may mutate the
44 process, so the AWS target's wholesale `build` spawns
45 `core/BuildChildRunner` with `cwd = <project root>`.
46- **Dev aligns the cwd instead.** The dev server runs in the caller's process
47 (alchemy's dev sidecar), so `inProjectCwd` sets the cwd across the window in
48 which vite evaluates the config module and restores it immediately after.
49 Consequence, upstream and unavoidable while the plugin keys off the cwd: one
50 process hosts the dev server of one SolidStart project at a time.
51- **No Cloudflare target.** Cloudflare deploys SolidStart through its native
52 Vite integration (`Cloudflare.Website.Vite`) with no nitro step at all.