SolidStart Integration
SolidStart is the meta-framework for
SolidJS, built on top of Vinxi and Vite.
solidjs-bext is the adapter that targets bext: you keep
SolidStart's authoring experience, and bext provides the HTTP
layer, cache, WAF, HTTP/2/3, and plugin ecosystem that every
adapter otherwise reinvents.
Preview release. The adapter and the Rust-side framework runtime in
crates/bext-framework-solidstartship as part of bext's E7 milestone. See the ecosystem roadmap for what's landed and what's still on the follow-up list.
Install#
bun add -d solidjs-bext
Peer dependencies: solid-start ^1 or @solidjs/start ^1.
Configure#
In app.config.ts (SolidStart 1.x):
import { defineConfig } from "@solidjs/start/config";
import bext from "solidjs-bext";
export default defineConfig({
server: {
preset: bext({
runtime: "bun",
}),
},
});
The adapter registers itself as a Vinxi server preset. SolidStart
then builds with server output, producing .output/server/index.mjs
plus a .output/public directory of hashed assets.
Options#
| Option | Type | Default | Description |
|---|---|---|---|
out |
string |
.output |
Output directory relative to the project root. |
runtime |
"node" | "bun" |
"bun" |
Preferred runtime for the SSR worker. Informational; bext decides. |
Build#
bun run build
The build emits:
.output/
public/ hashed JS, CSS, fonts
server/
index.mjs SSR entry exporting { handler }
bext-adapter.json metadata for the bext runtime
bext-adapter.json is the contract between solidjs-bext and
crates/bext-framework-solidstart. It looks like:
{
"adapter": "solidjs-bext",
"version": "0.1.0-preview",
"runtime": "bun",
"serverEntry": "server/index.mjs",
"clientDir": "public",
"generatedAt": "2026-04-11T12:00:00.000Z"
}
Serve#
Via bext.config.toml#
[framework]
type = "solidstart"
build_dir = ".output"
[build]
script = ".output/server/index.mjs"
watch_dirs = ["src"]
live_reload = true
Then:
bext serve
bext's vhost detects the project as SolidStart (on
solid.config.* or vite.config.* importing solid-start +
solid-start / @solidjs/start in package.json), reads the
build output, and dispatches requests to the SolidStart handler
through the framework runtime adapter.
Via bext new#
bext new my-solid-app --template @bext/starter-solid
cd my-solid-app
bun install
bun run build
bext serve
The starter ships with app.config.ts, an app shell, two routes
(/ and /about), and the bext.config.toml plumbing pre-wired.
How it fits together#
Three moving parts collaborate on every SolidStart request through bext:
solidjs-bext(this package) — SolidStart adapter + Vinxi preset. Runs at build time. Produces.output/andbext-adapter.json.crates/bext-framework-solidstart— RustFrameworkAdapterimplementation. Runs at server-config time. Detects the project, invokesbunx solid-start build(ornpx solid-start build), normalises the output, and vends a runtime adapter.bext-servervhost — per-request. Routes incoming requests to the SolidStart runtime adapter, which in turn dispatches to the Node / Bun subprocess running.output/server/index.mjs.
How it compares to the default Vinxi node-server preset#
The default node-server preset produces a standalone Node
server you run yourself. solidjs-bext skips the HTTP layer —
bext provides that — and just emits the compiled SSR entry plus
static assets. bext then adds TLS, HTTP/2/3, cache, WAF,
compression, and the full plugin ecosystem without SolidStart
needing to know about any of them.
What works today#
- File-system routing (
src/routes/*) - Dynamic routes with
[param].tsx - Catch-all routes with
[...rest].tsx - Server functions (
"use server"/createServerFn) - Route data (
createAsync/cache) - Islands via
clientOnlywrappers - Static assets served from
.output/public
The E7 adapter is a preview — per-request dispatch is not yet wired. If you need production traffic today, use the default node-server Vinxi preset behind bext as a reverse proxy (see multi-app) while the follow-up lands.
Current limitations#
- Subprocess dispatch is still TODO. For the E7 preview, the
runtime adapter is a descriptor only —
bext-framework-solidstart'shandle_requestreturns a not-yet-wired error. The follow-up is to teach bext-server's vhost to dispatch to the Node / Bun subprocess that imports.output/server/index.mjs, reusing the same subprocess plumbing bext already has for PHP / FastCGI. - No streaming responses yet. Solid's
renderToStreamcan return a streamingResponse. The preview buffers those. Piping them through bext's response writer lands with the streamingFrameworkAdapter::renderhook. - No edge runtime support. This adapter targets Node / Bun. Edge-style Workers-compatible output is out of scope for E7.
- No native Rust build.
solidjs-bextshells out tosolid-start build— the build is a Vite + Vinxi pipeline and rewriting it in Rust is out of scope for E7. A direct turbopack / bun pipeline is on the ecosystem roadmap.
Troubleshooting#
solid-start build produced no .output/ directory— the build ran but didn't emit the expected layout. Double-check that your Vinxi preset is actuallysolidjs-bextand not the defaultnode-server.SolidStartRuntime::handle_request is not wired yet— you're seeing the E7 descriptor-only limitation. Build works, detection works, but per-request dispatch is scheduled for the follow-up. Until then, use thenode-serverpreset behind bext as a reverse proxy if you need production traffic right now.- Legacy
solid-start(pre-1.0) — detection handles both the classicsolid.config.{js,ts}shape and the modernapp.config.tsshape. If you're stuck on an oldersolid-start, the adapter should still register, but some Vinxi hooks may not exist — consider upgrading to@solidjs/start ^1.
Related docs#
@bext/starter-solid— starter scaffold- bext framework overview — how adapters compose with bext's request pipeline
- PRISM data conventions — Remix-style
loader/actionexports in PRISM routes