bext.dev
DocsFramework Integrations
Framework Integrations4 min read
On this page

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-solidstart ship 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#

bash
bun add -d solidjs-bext

Peer dependencies: solid-start ^1 or @solidjs/start ^1.

Configure#

In app.config.ts (SolidStart 1.x):

ts
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#

bash
bun run build

The build emits:

code
.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:

json
{
  "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#

toml
[framework]
type = "solidstart"
build_dir = ".output"

[build]
script = ".output/server/index.mjs"
watch_dirs = ["src"]
live_reload = true

Then:

bash
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#

bash
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:

  1. solidjs-bext (this package) — SolidStart adapter + Vinxi preset. Runs at build time. Produces .output/ and bext-adapter.json.
  2. crates/bext-framework-solidstart — Rust FrameworkAdapter implementation. Runs at server-config time. Detects the project, invokes bunx solid-start build (or npx solid-start build), normalises the output, and vends a runtime adapter.
  3. bext-server vhost — 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 clientOnly wrappers
  • Static assets served from .output/public
Note

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's handle_request returns 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 renderToStream can return a streaming Response. The preview buffers those. Piping them through bext's response writer lands with the streaming FrameworkAdapter::render hook.
  • 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-bext shells out to solid-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 actually solidjs-bext and not the default node-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 the node-server preset behind bext as a reverse proxy if you need production traffic right now.
  • Legacy solid-start (pre-1.0) — detection handles both the classic solid.config.{js,ts} shape and the modern app.config.ts shape. If you're stuck on an older solid-start, the adapter should still register, but some Vinxi hooks may not exist — consider upgrading to @solidjs/start ^1.
Edit this page ↗Need a hand? ↗
FIND YOUR NEXT STEP

Start with a topic, a command, or a question.