Solidjs vs Astro with Solidjs
I was going to make a board game with solid.js, while researching I discovered that it can be used with Astro. My question is if you recommend using Astro with solid.js or just solid.js and why. I'm also curious which one performs better: using solid.js with Astro or using solid.js alone and why. I'm also curious about the pros and cons of solid.js alone and Astro with solid.js.
Finally, I would like to know what you recommend for my case of a board game, solid.js or Astro with solid.js.
13 Replies
1. SolidJS is browser framework.
2. Astro is a server-based web framework that integrates with various browser frameworks—delegating on page interactivity to those browser frameworks.
Astro itself specializes on the server-side-routing use case—i.e. going from one URL to the next it requires a full page reload.
That's not likely something you want to do with a board game. But Astro also supports API Routes so it is possible to have a single page in Astro and then explicitly create server endpoints to support the actions that happen on the page while the game progresses.
However SolidStart would be a better fit because the browser page can interact with the server, via actions and
"use server"
without having to explicitly lay out API Routes.
A word of warning however: Astro's 1.0 released in August 2022 and recently went 4.0; SolidStart is only on the release candidate for 1.0 right now.
So it should be relatively easy to get going with Astro because there is already a significant body of knowledge available.
In the short term with SolidStart you will likely need a healthy dose of early adopter doggedness and determination to keep digging and going—but it is likely to be a much better fit for your use case than Astro.You can create fully functional apps with Solid, either extending with SolidStart - or Astro with Solid.
In a more practical way, this is what you get with each:
:astro: + :solid:
Astro is mainly a static generated framework. Even the SSR mode will output a static HTML towards your user browser. You can add islands of interactivity (via Solid or other framework) and hydrate them on the client-side. This will enhance the funcionality with JS. But still, the islands will need sticthing if you want them to share state and data.
Accepting this tradeoff, this is a very powerful combo. Many people like it, including the Astro team themselves. :solid: You can have a traditional Single Page Application that will render and hydrate everything on the client-side. This is an acceptable approach if you can take that first-load perf hit - many dashboards and highly interactive apps go the SPA route still. You can circumvent lots of the perf issues with a service-worker or some other caching strategies. It takes work, but it can be done. :start: SolidStart takes Solid core and plugs in other tooling (namely Solid-Router and a server runtime) to give the isomorphic experience. With this you can handle your data and requests in a Server Action or Function. This will give you total control over your data and once it reaches the client-side, it will behave as a SPA. While SolidStart will give you a larger bundle footprint than Astro, it will offer more control over your data, it will allow you to make your apps more interactive, and communication between components will be seamless. My take If you know your app will be highly interactive, like a game, go with SolidStart from the beginning. Using Astro will be pointless if every component you get is interactive - the initial gains from a "0 javascript" bundle-size will quickly melt away as you start adding interactivity everywhere and even bringing external dependencies to handle data between separated islands.
Accepting this tradeoff, this is a very powerful combo. Many people like it, including the Astro team themselves. :solid: You can have a traditional Single Page Application that will render and hydrate everything on the client-side. This is an acceptable approach if you can take that first-load perf hit - many dashboards and highly interactive apps go the SPA route still. You can circumvent lots of the perf issues with a service-worker or some other caching strategies. It takes work, but it can be done. :start: SolidStart takes Solid core and plugs in other tooling (namely Solid-Router and a server runtime) to give the isomorphic experience. With this you can handle your data and requests in a Server Action or Function. This will give you total control over your data and once it reaches the client-side, it will behave as a SPA. While SolidStart will give you a larger bundle footprint than Astro, it will offer more control over your data, it will allow you to make your apps more interactive, and communication between components will be seamless. My take If you know your app will be highly interactive, like a game, go with SolidStart from the beginning. Using Astro will be pointless if every component you get is interactive - the initial gains from a "0 javascript" bundle-size will quickly melt away as you start adding interactivity everywhere and even bringing external dependencies to handle data between separated islands.
Thanks for your two answers. But I didn't understand what SolidStart does when you say it handles data and requests on both the server and the client. What do you mean by that, when would it be used or how would it be used?
The most basic example
Executing
logHello('World')
in the browser but the console.log(message)
actually running on the server without having to:
1.) Explicitly create an API endpoint on the server and
2.) Coding a fetch
in the browser to get message
from the browser to the server.SolidStart Release Candidate Documentation
SolidStart Release Candidate Documentation
Early release documentation and resources for SolidStart Release Candidate
Under the hood it's a platform-specific RPC mechanism (an approach which has gained popularity with tRPC) but it uses seroval as it's serialization mechanism which is more capable than JSON.
GitHub
GitHub - lxsmnsyc/seroval: Stringify JS values
Stringify JS values. Contribute to lxsmnsyc/seroval development by creating an account on GitHub.
Let's see if I understood:
An action is a function defined in SolidStart that represents a data request or an asynchronous operation.
You can think of them as functions that perform specific tasks, such as sending data to a server, performing complex calculations, or performing read/write operations on a database.
An action is practically one function, both can perform operations and return results. But I assume that actions in SolidStart are specifically designed to handle data requests and asynchronous operations, and I assume that they provide additional tools to handle and track these requests elegantly.
Regarding the execution of the function on the client and server side, I think I understand what the purpose of executing it on the server side can be, for example in my case when a piece moves from place to place, I can validate the action of moving the piece on the server side to check that the move follows the rules of the game and is therefore "legal". Although it is still not clear to me what an action on the client side would do...
I assume that they provide additional tools to handle and track these requests elegantly.useSubmission
what an action on the client side would doAn action can return a result (
submission.result
) which in turn can advance the client's state.
Often a successful action on the client will result in a change in the client's non-ephemeral state which is reflected in a route navigation; e.g. completing a valid move will move the game forward from turn n
to turn n+1
.
Now if you are implementing an ephemeral solitaire on the browser then your client may not need server support at runtime. But a game supporting two opponents separated by the internet is going to require some sort of server support for the clients.GitHub
GitHub - solidjs/solid-router: A universal router for Solid inspire...
A universal router for Solid inspired by Ember and React Router - solidjs/solid-router
Please correct me if I'm wrong:
Then a client-side action could be used for immediate interaction tasks with the player, such as validating and displaying possible moves, while a server-side action would be needed to validate the actual moves made by the players and ensure the integrity of the game.
In this context action has a special meaning with respect to the router, so
immediate interaction tasks with the player, such as validating and displaying possible movesmay not even be considered an "action" depending if it alters non-ephemeral state. Non-ephemeral state tends to end up on the server in some form because that is what is necessary to present the user "with the state of their most recent session" even if they move to an entirely different computer and browser.
An action could this be? configure other game options, such as the number of players or specific rules. When a user selects a board, this action not only changes the current board, but also updates other game settings.
It's just that this is the first time I've seen the word non-ephemeral, so I'm having a hard time interpreting it correctly.
It boils down to the URL in the address bar.
Some people don't consider them "important" when it comes to web "apps" but perhaps they didn't think about it long and hard enough.
To the server the URL is the identifier of the page/state that it has to send to the browser on initial load.
So any state that has to be available on the server for the user to be able to "pick up their last session" where they left off before abandoning it (shutting down browser, computer) is non-ephemeral.
Any state that is ephemeral will be gone and therefore not be represented on the page the next time they initial load from that URL.
Any state that is ephemeral will be gone and therefore not be represented on the page the next time they initial load from that URL.
configure other game options, such as the number of players or specific rules. When a user selects a board, this action not only changes the current board, but also updates other game settings.Can they set up all this before the game the day before and then carry on the next day from a different computer and browser? If yes then we are talking about non-ephemeral state.
oohh, that means, so if one user plays against another, it would be nice if it wasn't ephemeral, in case they accidentally close the page or reload it. and if the game is already over I can make it ephemeral. Would the idea be something like this?
yes, then not ephemeral, I use it when I want a certain state to be maintained even if I close the page or change browsers or computers 🤔