elysia-solid
v0.0.4
Published
Full-stack framework: **Elysia** (server) + **Solid.js** (client islands) + **Vite** (dev/build).
Downloads
456
Readme
elysia-solid
Full-stack framework: Elysia (server) + Solid.js (client islands) + Vite (dev/build).
Write your server with Elysia and JSX. Mark interactive components with "use client". The framework handles SSR, hydration, and production builds automatically.
Install
bun add elysia-solid elysia solid-js vite vite-plugin-solidQuick Start
vite.config.ts
import { defineConfig } from "vite";
import { elysiaSolid } from "elysia-solid/vite";
export default defineConfig({
plugins: [
elysiaSolid({
entry: "./app.tsx",
}),
],
});app.tsx — Elysia server with JSX
import { Elysia } from "elysia";
import { solid } from "elysia-solid";
import Counter from "./islands/Counter";
function Layout(props: { title: string; children?: any }) {
return (
<html lang="en">
<head>
<title>{props.title}</title>
</head>
<body>{props.children}</body>
</html>
);
}
export default new Elysia()
.use(solid())
.get("/", () => (
<Layout title="Home">
<h1>Hello from Elysia</h1>
<Counter initial={0} />
</Layout>
));islands/Counter.tsx — Interactive island
"use client";
import { createSignal } from "solid-js";
export default function Counter(props: { initial: number }) {
const [count, setCount] = createSignal(props.initial);
return (
<div>
<p>Count: {count()}</p>
<button onClick={() => setCount((c) => c + 1)}>+</button>
</div>
);
}Development
bunx --bun viteThe dev server starts with HMR. Server file changes trigger a page morph (no full reload). Island changes use Solid's fast refresh.
Production Build
vite build # builds client assets + server bundle
bun dist/server/app.js # run production serverThe plugin handles both build phases automatically via Vite's environment API. The output is a self-contained server that serves static assets and renders SSR HTML with hydration scripts.
How It Works
Islands Architecture
Any component file with "use client" at the top becomes an island:
- SSR — The component renders to HTML on the server inside a
<div data-island>wrapper with serialized props - Hydration — The client runtime finds
[data-island]elements and hydrates them with Solid'shydrate(), reusing the server-rendered DOM - Lazy loading — Each island is code-split and loaded on demand
Server Rendering
Routes return JSX directly. The solid() plugin auto-detects HTML responses and sets proper headers/DOCTYPE. For explicit control, use the html() helper:
import { html } from "elysia-solid";
app.get("/", () => html(<Layout><Page /></Layout>));HTMX Support
Islands inside HTMX-swapped fragments hydrate automatically via a MutationObserver. No extra configuration needed.
API
elysiaSolid(options) — Vite Plugin
import { elysiaSolid } from "elysia-solid/vite";| Option | Type | Description |
|--------|------|-------------|
| entry | string | Path to the Elysia app entry file |
solid() — Elysia Plugin
Registers a mapResponse hook that converts Solid SSR output to proper HTML responses.
html(input) — Response Helper
Renders JSX to an HTML Response with DOCTYPE and content-type headers.
License
MIT
