Renderizado en el servidor en Solid con SolidStart
Crea una app con SolidStart v2 y explora datos renderizados en servidor, query y createAsync, precarga de rutas, funciones de servidor y despliegue.
SolidStart v2 (@solidjs/start 2.x) · Solid v1 · Node.js 24+ · Vite 8
SolidStart es el framework full-stack de SolidJS. Incorpora a los componentes de Solid enrutamiento basado en archivos, renderizado en el servidor y funciones de servidor, y cumple el papel que Next.js desempeña para React y SvelteKit para Svelte.
Si ya escribes componentes de Solid, lo difícil de dar el salto al full-stack son los tutoriales. La mayoría siguen usando app.config.ts y Vinxi, y ninguno de los dos existe en la versión mayor actual. En este artículo se construye una pequeña aplicación con SolidStart v2 que carga datos desde el servidor e incluye una página de detalle con precarga. Después se abordan las funciones de servidor, la configuración del renderizado, el despliegue y si el ecosistema está lo bastante maduro como para elegirlo frente a un stack de React. Se da por hecho que conoces los patrones a nivel de componente que se tratan en buenas prácticas de SolidJS.
Puntos clave
- SolidStart v2 alcanzó la versión estable el 4 de agosto de 2026. Está pensado para Solid v1, sustituye Vinxi por la Environment API de Vite, requiere Node.js 24+ y Vite 8, y se configura en
vite.config.ts. - En SolidStart v2, los datos de una ruta se cargan envolviendo una función asíncrona en
queryde@solidjs/routery leyéndola concreateAsync. - Una directiva
"use server"al principio del cuerpo de una query hace que esa función se ejecute en el servidor, donde puede leer secretos y datos de sesión. - Exportar
route.preloaddesde un módulo de ruta inicia la query de la ruta antes de que se renderice el componente de la página. - SolidStart v2 se despliega mediante plugins de Vite (Nitro v3, Cloudflare, Netlify) y no mantiene adaptadores de hosting propios.
¿Qué es SolidStart y en qué punto se encuentra v2?
SolidStart es la capa de meta-framework que se sitúa sobre Solid. Solid renderiza componentes. SolidStart añade a su alrededor enrutamiento, renderizado en el servidor, carga de datos y un pipeline de compilación y despliegue.
SolidStart v2 alcanzó la versión estable el 4 de agosto de 2026. Vinxi ha desaparecido y v2 se apoya en su lugar en la Environment API de Vite. Necesitas Node.js 24 o superior y Vite 8, y la configuración del framework se encuentra ahora en vite.config.ts en lugar de en app.config.ts. v2 está diseñado para Solid v1. El anuncio de la Release Candidate de Solid 2.0 indica que SolidStart solo recibirá ya versiones de mantenimiento y que, en Solid 2.0, un modo Start integrado en el núcleo de Solid asumirá su papel. Las aplicaciones que ya ejecutan SolidStart en producción siguen funcionando. El código que aparece a continuación está pensado para Solid v1 y SolidStart v2. Si vas a actualizar una aplicación existente en v1, sigue la guía de migración desde v1.
Crear un proyecto de SolidStart
Para generar la estructura de un proyecto, ejecuta el inicializador de Solid y elige la plantilla de SolidStart cuando se te pregunte:
npm init solid
# or: pnpm create solid
cd my-app
npm install
La aplicación se configura en vite.config.ts. La configuración mínima de la guía de primeros pasos es la siguiente:
import { defineConfig } from "vite";
import { solidStart } from "@solidjs/start/config";
export default defineConfig({
plugins: [solidStart()],
});
Para producción, solidStart() se combina con un plugin de servidor, por ejemplo Nitro v3. La referencia de configuración de solidStart deja los ajustes de Nitro fuera de solidStart(): deben ir en una clave nitro independiente en el nivel superior.
Cada archivo dentro de src/routes se convierte en una página o en un endpoint de API. La página de rutas de API de v2 explica que los endpoints siguen las mismas reglas de correspondencia entre archivo y ruta que las páginas. Un alias ~ integrado apunta a la raíz de la aplicación, de modo que, con la configuración predeterminada, ~/lib/db corresponde a src/lib/db.
Cargar datos en el servidor con query y createAsync
En SolidStart, los datos de una ruta provienen de una función asíncrona envuelta en query de @solidjs/router. Un componente los lee después mediante createAsync. Este es el patrón que utiliza la documentación de obtención de datos de v2. La documentación también indica que SolidStart v2 funciona con Solid Router v1 o con TanStack Solid Router v1. Los ejemplos de este artículo usan Solid Router.
Empieza con un módulo de datos en src/lib/posts.ts. Utiliza un array en memoria para que el ejemplo funcione sin base de datos:
export type Post = { id: string; title: string; body: string };
const posts: Post[] = [
{ id: "1", title: "Hello SolidStart", body: "First post." },
{ id: "2", title: "Server functions", body: "Second post." },
];
export async function listPosts() {
return posts.map(({ id, title }) => ({ id, title }));
}
export async function findPost(id: string) {
return posts.find((p) => p.id === id) ?? null;
}
La ruta del listado de posts:
import { For } from "solid-js";
import { createAsync, query, type RouteDefinition } from "@solidjs/router";
import { listPosts } from "~/lib/posts";
const getPostList = query(async () => {
"use server";
return listPosts();
}, "post-list");
export const route = {
preload: () => getPostList(),
} satisfies RouteDefinition;
export default function PostsPage() {
const list = createAsync(() => getPostList());
return (
<ul>
<For each={list()}>
{(post) => (
<li>
<a href={`/posts/${post.id}`}>{post.title}</a>
</li>
)}
</For>
</ul>
);
}
La página de detalle es una ruta dinámica que recibe un parámetro id. La documentación de enrutamiento de v2 describe la sintaxis de nombres de archivo para los segmentos dinámicos.
import { Show } from "solid-js";
import { createAsync, query, type RouteDefinition } from "@solidjs/router";
import { findPost } from "~/lib/posts";
const getPostById = query(async (id: string) => {
"use server";
return findPost(id);
}, "post-by-id");
export const route = {
preload: ({ params }) => getPostById(params.id),
} satisfies RouteDefinition;
export default function PostPage(props: { params: { id: string } }) {
const post = createAsync(() => getPostById(props.params.id));
return (
<Show when={post()} fallback={<p>Post not found.</p>}>
{(p) => (
<article>
<h1>{p().title}</h1>
<p>{p().body}</p>
</article>
)}
</Show>
);
}
El segundo argumento de query es la clave de caché, así que asigna a cada query la suya propia. La exportación route.preload inicia la query antes de que se renderice el componente de la página, lo que significa que la carga de datos comienza en el mismo momento que la navegación.
Formularios, mutaciones y revalidación
Escribir datos de vuelta en el servidor funciona de forma distinta a leerlos. Una mutación tiene que modificar el estado en el servidor y, a continuación, indicar a la página que sus lecturas en caché están obsoletas. En v2, las escrituras se realizan mediante action de Solid Router, con una directiva "use server" dentro del cuerpo de la acción cuando el trabajo debe ejecutarse en el servidor. La página de mutación de datos de v2 incluye los ejemplos actuales de formularios, la gestión de los estados pendiente y de error, y el paso de argumentos adicionales con .with().
La parte de lectura de la revalidación se mantiene respecto a la sección anterior. Cada query se almacena en caché bajo su clave ("post-list" y "post-by-id" en los ejemplos anteriores), y createAsync vuelve a leer los datos cuando se revalida esa entrada de la caché. Cuando una acción se completa correctamente, Solid Router revalida de forma predeterminada todas las queries activas de la página. Para actualizar solo algunas de ellas, pasa claves a revalidate: getPostList.key afecta a todas las instancias de una query y getPostById.keyFor(id) afecta a una sola. La documentación de obtención de datos delega el comportamiento de la caché en Solid Router, y la página de revalidación del router lo explica en detalle.
Usar nombres de clave de query claros y estables compensa cuando se acota la revalidación. Una mutación que añade un post solo necesita actualizar "post-list", mientras que una edición también necesita actualizar "post-by-id".
¿Qué hace “use server”?
Colocar la directiva "use server" al principio del cuerpo de una función hace que esa función se ejecute en el servidor, incluso cuando se invoca desde un componente. Por eso una query marcada de esta forma puede leer secretos de process.env y datos de sesión. La documentación de obtención de datos de v2 lo muestra con useSession de @solidjs/start/http en su ejemplo de código exclusivo del servidor.
Dentro de "use server" | Fuera de "use server" |
|---|---|
Secretos de entorno (process.env.*) | APIs del navegador (window, localStorage, DOM) |
| Acceso a base de datos y sesión | Estado de la UI que reside en los componentes |
Helpers de @solidjs/start/http | Cualquier cosa que deba ejecutarse con un clic sin realizar una petición |
En una aplicación de SolidStart, el estado de la UI pertenece al cliente. El servidor gestiona los datos, y las signals y los stores gestionan el estado de interacción, una división que se trata en gestión del estado en SolidJS.
SolidStart v2 también reconoce los imports marcadores server-only y client-only. Si añades uno a un módulo, importarlo desde el lado equivocado (código de servidor en el cliente, o al revés) provoca un fallo en el servidor de desarrollo o en la compilación, de modo que el error nunca llega a los usuarios. La referencia de configuración indica que @solidjs/start/http y @solidjs/start/middleware ya están marcados como server-only. Durante el desarrollo también dispones de una barra de herramientas que muestra los errores de la aplicación y las llamadas a funciones de servidor. Nunca se incluye en una compilación de producción.
Modos de renderizado en SolidStart
En SolidStart v2, el comportamiento del renderizado se configura a través del plugin solidStart() y del plugin de despliegue con el que se combina, ambos declarados en vite.config.ts. Para conocer las ventajas e inconvenientes conceptuales del renderizado en el servidor, el streaming y la generación estática, consulta los 10 principales patrones de renderizado. Esta sección solo explica dónde se definen esas opciones en SolidStart.
Como app.config.ts ya no existe, ninguna opción de renderizado de la época de v1 que encuentres en artículos antiguos se aplica tal cual. Para conocer las opciones que ofrece v2, consulta la referencia de configuración de solidStart() y la documentación de los plugins de despliegue.
Cuando una página se renderiza en el servidor, los usuarios ven el marcado antes de que el JavaScript del cliente lo haya hidratado. Las grabaciones de sesión (session replays) de aplicaciones con SSR ponen de manifiesto este desfase: un usuario pulsa un botón que se muestra correctamente pero no hace nada, y vuelve a pulsarlo cuando los manejadores de eventos ya están enlazados.
Desplegar SolidStart v2
SolidStart v2 no tiene adaptadores de hosting propios. Se despliega mediante plugins de Vite, y el anuncio de v2 menciona tres destinos compatibles: el plugin de Vite de Nitro v3 (todavía en beta según ese anuncio), el plugin de Vite de Cloudflare y el plugin de Vite de Netlify. La guía de primeros pasos enlaza a una página de plugins de despliegue que explica la configuración del entorno de ejecución en producción para cada uno de ellos.
El verdadero coste de elegir SolidStart frente a un stack de React es el ecosistema. React cuenta con muchas más bibliotecas de componentes de terceros, integraciones de autenticación y plantillas de hosting, y los equipos que trabajan con Solid tienen que escribir por su cuenta una mayor parte de ese código de integración. La comparativa entre SolidJS y React contrapone esa diferencia con el modelo de renderizado de Solid. Ten en cuenta también que SolidStart v2 está en fase de mantenimiento mientras Solid 2.0 avanza hacia el modo Start.
Conclusión
SolidStart v2 es una forma estable y nativa de Vite de añadir renderizado en el servidor a aplicaciones con Solid v1. La carga de datos se reduce a tres piezas: query, createAsync y una directiva "use server", junto con route.preload para la obtención anticipada. El siguiente paso es generar un proyecto con npm init solid, añadir las dos rutas de posts anteriores y, después, implementar una mutación siguiendo la sección de mutación de datos de la documentación de v2.
Preguntas frecuentes
¿Funciona SolidStart v2 con Solid 2.0?
No. SolidStart v2 está diseñado para Solid 1.x y ninguna versión de SolidStart es compatible con Solid 2.0. La Release Candidate de Solid 2.0 retira SolidStart y reparte sus piezas: el núcleo de Solid se encarga ahora de las funciones de servidor, el modo Start gestiona el servicio de la aplicación y un paquete independiente y neutral respecto al router se ocupa del enrutamiento basado en el sistema de archivos. Las aplicaciones existentes con SolidStart siguen funcionando, SolidStart sigue recibiendo versiones de mantenimiento y una guía de migración oficial explica cómo pasar al modo Start.
¿Qué diferencia hay entre TanStack Start y SolidStart con TanStack Router?
Son opciones distintas. SolidStart v2 es agnóstico respecto al router y funciona tanto con el Solid Router v1 oficial como con TanStack Solid Router v1, por lo que puedes usar el enrutamiento de TanStack sin abandonar SolidStart. TanStack Start es un metaframework independiente con una variante para Solid, publicada como @tanstack/solid-start, que ya cuenta con una versión beta para Solid 2.0. Para Solid 2.0, el starter fullstack-tanstack combina el modo Start con TanStack Router y TanStack Query.
¿Qué son las single-flight mutations en SolidStart?
Las single-flight mutations devuelven los datos actualizados en la misma respuesta del servidor que la propia mutación. Cuando una acción del lado del servidor modifica datos que la vista actual ha precargado, o redirige a una página cuyos datos están precargados, SolidStart revalida esos datos en el servidor y los entrega en el mismo viaje de ida y vuelta. El cliente no necesita realizar una segunda tanda de peticiones, por lo que no se produce una cascada de peticiones tras una escritura.
¿Qué cambia al actualizar una aplicación de SolidStart v1 a v2?
La actualización requiere Node.js 24 y Vite 8. La configuración del framework pasa de app.config.ts a vite.config.ts, donde solidStart() se registra como plugin de Vite, y la Environment API de Vite sustituye a Vinxi. La guía de migración oficial también detalla los cambios en las rutas de importación, los tipos de entorno de TypeScript, el entorno de ejecución del servidor y el middleware. Revisa las rutas de importación y el código de middleware de v1 con ayuda de la guía en lugar de copiarlos tal cual.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.
Star on GitHub12k