- 16 min to read
SolidJS Library - a practical guide to building simple and performant user interfaces
Build a fast website with SolidJS! This practical guide covers setup, styling, state management, data fetching, and more. By building a movie app, you'll learn how to use SolidJS and optimize your projects for speed and efficiency.
In this practical guide to SolidJS, you will learn about SolidJS, its setup procedure, and file organization. You will discover how to add components, style, and manage state in a SolidJS app. Furthermore, you will explore how to fetch data from a server, pass data between components and navigate between pages.
You will build a simple movie app that displays lists of movies that allows searching and viewing details. You will utilize Open Movie Database (OMDb) API to get the movie data.
By the end of this article, You'll have an in-depth knowledge of how SolidJS functions and how to use it in rapidly developing effective and fast websites.
- Introduction to SolidJS
- How to set up a SolidJS project
- Project Structure
- Solid Components
- Styling in SolidJS
- State management
- Fetching data
- Control flow
- Passing data between components
- Routing and Navigation
- Handling events
- Optimization best practices
- Building and deploying Solid projects
Introduction to SolidJS
SolidJS's fine-grained reactivity mechanism is one of its standout characteristics. It ensures that the UI always represents the most current state of the application by updating the impacted components immediately whenever a dependent changes. By only updating the UI elements that are affected by changes, this reactive approach is much more efficient than other libraries and frameworks at updating the user interface.
SolidJS supports modern framework features such as:
- Streaming SSR
- Progressive hydration
How to set up a SolidJS project
You'll use a Vite template which has the necessary boilerplate code to create a SolidJS project.
npx degit command to clone the template from the repository
solid/js/templates/js to your project folder in a new terminal window:
solid-movie with the relevant name for your application.
If you prefer to use TypeScript, run the following command instead:
/js template and
/ts template both produce the same results.
When the template has been cloned to your project folder, go to that directory and install the project's required dependencies:
Use the following command to launch the development server after the dependencies are successfully installed:
To access the SolidJS launch page, open your browser at http://localhost:3000/.
Here is a sample file structure for a SolidJS application:
src: you will place your application's source code in this directory. It might have subdirectories to arrange your resources, assets, and other pieces.
assets: static files used by the application, such as images, fonts, and other resources, can be placed in this directory. The assets can be arranged according to the type or function in the application.
App.js: the bootstrapping of the components and any global configurations or providers are done in this file, which also serves as the SolidJS application's entry point.
Index.js: this file is in charge of rendering the primary SolidJS application component, App.js, into the HTML document and attaching it to the DOM.
vite.config.js: it is a configuration file used by Vite, the default build tool suggested for usage with SolidJS.
This gives a general understanding of the SolidJS file structure. Although the precise file structures may vary based on the size and complexity of your application, you can arrange your files in a way that makes sense for your particular use case.
In a SolidJS application, components serve as the basic building blocks and encapsulate the UI logic and state for individual sections. Components are defined as reactive functions, which update dynamically as their dependencies change, following the reactive programming paradigm.
Components in SolidJS are described as functions that return a UI template. These functions return JSX or plain HTML and accept reactive state and props as inputs. Functional components are reusable and maintainable due to their simplicity and ease of reasoning.
src directory, create a
components folder that will house the necessary components for the app. Next, create three files for the components
Write the following code in the
This code snippet defines the functional component
MovieCard. It returns a div element with an image, a title, the year, and a "See details" button. The
MovieCard component is exported at the end of the code so it can be imported and used in different parts of the application.
Now, in the
MovieList component is created. The component displays a movie card after importing the MovieCard component from "./Movie-Card". The title is shown in an
h1 element inside the
MovieList component using a
It is possible to return several elements from a component without needing to wrap them in a container element by using the shorthand syntax of Fragments (<></>). Then the component is exported at the end of the code.
MovieCard component is built with just one
div. It is exported, making it accessible across the app. Now import the components into the root component
You import the
MovieDetails components from their respective files.
Styling in SolidJS
Making interactive and aesthetically pleasing web applications requires styling.
These are just a few of the styling methods offered by SolidJS:
- Inline styling
- CSS classes
- CSS-in-JS libraries
- CSS modules
- CSS libraries
- Dynamic style utilizing reactive variables
These methods for styling in SolidJS enable you to design well-structured, modular, and dynamic user interfaces.
In this application, you will make use of Solid-bootstrap in order to speed up the development process. Solid Bootstrap is a library of pre-made UI elements for Solid applications built on the Bootstrap framework. The components and style possibilities offered by Solid-Bootstrap are numerous.
To use it in your Solid project, execute the subsequent command to install solid-bootstrap using npm or yarn:
Solid Bootstrap offers pre-built CSS files that you may use to customize your application.
Add the CSS file to your
Now your SolidJS components can import and utilize the
Proceed to style your components using
The components for the button and card are imported from solid-bootstrap. An image is displayed using the
Card.Img element, and the variant="top" parameter specifies that the picture should appear at the top of the card. A
Card.Title and a
Card.Text elements are found in the "Card.Body" element and are used to display the movie's title and its release year, respectively. A button is displayed last, and the variant="primary" prop specifies that the button should be blue.
Now update the
Row elements from the
solid-bootstrap library are imported. There is a search input field and a section has a row of movie cards that are individually presented using the "Col" component in a column.
h1 tag can be found in the component's return statement. It also has two
Card components, the first of which has two
Card.Text components and a
Card.Img component for the display of the movie's plot and its year of release. The director, stars, and rating of the film are displayed using three
Card.Text components found in the second
State management is a vital component of developing contemporary web applications, and SolidJS provides a variety of methods for doing so effectively. The reactive state, which enables developers to create and manipulate application states reactively, is the basic idea behind SolidJS's state management system. With a reactive state, there is no need for manual DOM modification because the user interface is updated immediately anytime the underlying state changes.
SolidJS offers robust capabilities for managing states reactively and effectively, whether it be component-level state, props, context, or global state management via the store API.
The state is commonly managed in SolidJS using
Signals, which generates a reactive state value and a setter function that may be used to update the value. Solid's reactivity is built on
Signals. They include dynamic values - when you modify a signal's value, everything that relies on it is updated immediately. The initial value is the parameter used to construct the
Signal, and the return values are an array with two functions a getter and a setter. The first returned value is not the value itself, but rather a getter, a function that returns the current value.
solid-js to create a signal and use it in the
createSignal function from SolidJS defines three
movies: an empty array that will be used to store the list of movies that was fetched from an external API.
searchWord: a string that has the value "men" as its starting value and represents the user's current search query.
loading: a boolean that, by default, is initialized to false and determines whether the component is presently loading data.
The value of the search input field is currently set using
searchWord(). Depending on whether the
loading signal is
true, the movie list section conditionally displays a spinner.
In a SolidJS application, fetching data entails sending asynchronous queries to a remote API or server, that are subsequently used to update the user interface (UI). You will use either built-in browser APIs like
fetch or third-party libraries like
Axios since SolidJS lacks built-in data fetching functionality. It's crucial to adhere to best practices for handling errors, handling retries, and controlling the lifecycle of the fetch operation while retrieving data in a SolidJS application.
MovieList component, you will use the
fetch API to retrieve movies from OMDb. To receive an API key that will be required while making API requests, you must register on the website.
Create a ".env" file at the root of your app to keep this API key as an environment variable. The environment variables stored in the
.env file are loaded by Vite by use of dotenv. Add the values in a variable in the
.env file like follows:
The function that will make the API calls will be created in a
Effects are intended for side effects that read the reactive system but do not write to it. Effects are common ways to make code segments run whenever dependencies change, such as when manually altering the DOM or making API calls.
createEffect provides a new calculation that runs the supplied function in a tracking scope while continuously tracking its dependencies and rerunning the function whenever the dependencies change.
First, import the
createEffect to use it. Environment variables declared in
.env files at build time are used to define the
apiKey constant. It guarantees that the API key is kept private and hidden from view in the client-side code.
The effect gets triggered when the component renders and runs the asynchronous function
getMovies(). Following that, a
GET request is sent with the search criteria and API key supplied to the OMDB API. The
setMovies() function stores the search array in the component's state. In order to signal that the process is complete,
setLoading(false) is called at the end.
Control flow is a crucial idea in programming that enables programmers to execute code only when specific conditions are met or to carry out repetitive activities. Reactive programming techniques and specific directives for conditional rendering and iteration are used in SolidJS to accomplish control flow. These capabilities offer a powerful and adaptable method for handling conditional logic and dynamic rendering in SolidJS applications.
for directive in SolidJS allows you to iterate over arrays or other iterable data and dynamically render items for each entry in the array.
To use the
for directive, you have to import it first in the
The code determines whether
movies() is truthy (not null, undefined, or empty) and checks whether the length of the
movies() array is greater than zero. If both requirements are satisfied, it renders a
Row component with a loop using the
For directive from SolidJS.
It renders a
MovieCard component wrapped in a
Col component with given column widths for various screen sizes (sm: 12 columns for small screens, md: 3 columns for medium screens) for each movie object in the
movies() array. Employing conditional rendering, a
p tag is used to display a message if the
movies array is empty.
Passing data between components
Props are used to facilitate data flow between components. Props are values or objects that are sent from a parent component to a child component. They can be defined in a child component and used to access data coming from the parent component.
MoiveList component, you will pass a movie item as a prop to the
For efficient rendering in SolidJS, the
key prop is set to
movie.imdbID to provide a distinct identity for each
MovieCard component in the loop.
Then proceed to the
MovieCard component to receive the prop and utilize it.
This component receives a prop named
movie, which is an object that includes information about a movie, such as a
The component then utilizes object destructuring to extract these properties and use them in the Bootstrap Card component.
This is what your app will look like:
Routing and navigation
SolidJS uses Solid Router to implement routing and navigation. Solid Router is a multipurpose router for SolidJS. Iit functions whether rendering is on the client or the server. It draws on and integrates the React Router and Ember Router principles. Route definitions can be made explicitly in the JSX template for your app, but you can also pass your route information as an object. It allows hierarchical routing, allowing navigation to modify only a portion of a component rather than entirely replacing it. You can utilize it with suspense, resources, and lazy components because it supports all of Solid's SSR methods and has Solid's transitions built in.
solid-router is required in order to use it. It may be installed using a package manager like npm or yarn.
Now you can proceed to set up the application's routes.
src/index.jsx file, import and wrap your root component within the
Router gives you a context that enables you to display the routes throughout the app. Now, open the
src/App.jsx file to configure app routes:
Route components from the
@solidjs/router library are imported.
This code leverages the Solid Bootstrap
Container component to enclose and add padding to the application's content. A navigation bar is made using the
Navbar component from the same package. The
Routes component defines the routes, while the
Route component specifies the path and the associated component to render. To make sure that the navigation is handled by the router, @solidjs/router supplies the
A component that should be used in place of the standard anchor tag.
The root path
/ is the first route specified, and it renders the
MovieList component. The
/movie-details/:id path, which is the second declared route, renders the MovieDetails component. The colon (:) in the path denotes that a dynamic parameter (the movie id) will be passed.
You have to set up the "See details" button to navigate to the
The link to the movie details page is made using an
A component from the router library with the href property pointing to
Then finishing up on the
The component imports the
Spinner components from Solid Bootstrap as well as the
createEffect utilities from the SolidJS library. Additionally, the
useParams method from the
@solidjs/router package is imported to take the id parameter out of the URL.
useParams obtains a reactive, store-like object that contains the Route's current route path parameters.
The component specifies the
loading is a boolean that is set to
true while the API request is being made and set to
false when the request is finished.
movieDetail stores an object containing the details of the movie that were fetched from the API.
When the component gets rendered, the effect specified by the component is executed. The effect sends an asynchronous request to the OMDb API to retrieve the movie information associated with the URL's extracted id parameter. The
loading signal is set to
false and the
movieDetail signal is updated with the response data when the API response is received.
While the API request is being processed, the component displays a loading spinner. Once the API response has been received, the component displays the movie details.
movie-details page now looks like this:
In a SolidJS project, handling events involves capturing user interactions like button clicks, form submissions, and keyboard events and reacting to them with the required logic. SolidJS offers event bindings that capture several types of events, including
onSubmit, and others, which may be incorporated as attributes on JSX elements. With the aid of these event bindings, you can affix event handlers to specific elements.
handleSearch function serves as an event handler for the search input field's
onChange event, which modifies the
searchWord signal to reflect the most recent value that the user has entered. When the function is being executed, the effect automatically subscribes to any signals that are read and reruns whenever any of them change.
Optimization best practices
SolidJS is created to be performant and versatile. It includes a variety of optimization approaches to aid in enhancing your application's speed and effectiveness. Here are some best recommendations for improving SolidJS applications:
- Utilize dynamic imports - SolidJS enables dynamic imports, which helps speed up your application's initial load time. Instead of loading everything at once, you may use the
lazyfunction to just load components or modules as needed.
- Avoid excessive renders - one of the main advantages of SolidJS is its capacity to re-render the UI components that have changed. The timing and frequency of your re-renders must be considered, though. If any resources or subscriptions need to be cleaned up once a component is unmounted or modified, use the onCleanup lifecycle method.
- Utilize memoization - memoization is a performance-enhancing method that involves caching the outcomes of intensive function calls. The createMemo method in SolidJS can be used to store a function's output in a memo. It can lower the number of pointless re-renders and boost your application's overall performance.
- Employ the
keyproperty - the ability of SolidJS to effectively update the DOM depends on the ability to uniquely identify elements in a list using the
keyproperty. It's crucial to avoid using the index as the key and use a reliable, distinct key for each element.
- To enhance rendering, use
async- until the subsequent render cycle, a function's execution can be postponed using SolidJS'
deferfunction. To run a function asynchronously, you can employ the
Developers may optimize SolidJS applications to deliver a quick and effective user experience by adhering to these best practices.
Building and deploying Solid projects
SolidJS projects require several processes to build and deploy, including code bundling and compilation as well as optimization, deployment, and monitoring. All these processes are handled by Vite, a tool for building and deploying SolidJS apps. It is an effective tool that can assist developers in streamlining their development processes and creating high-performance SolidJS applications for use in real-world scenarios. With features like hot module replacement, improved production builds, and quick development server startup times, it is a fast and lightweight tool that provides a modern development experience.
When you're prepared to build the application for usage in production, execute the following command:
It will start Vite's build process, which bundles the application code into optimal files prepared for production deployment. The
dist directory will be the default location for the stored files.
You can deploy the newly generated files to a hosting platform or production server once the build procedure is complete. It can entail deploying to a Platform as a Service (PaaS), employing a cloud-based hosting provider, or uploading the files to a web server.
After deploying the files, you can serve them using a web server or hosting provider of your choice. The server can be set up to serve the SolidJS application's entry point, the index.html file, and any additional static files generated during the building process.
The meta framework for SolidJS
It is also worth noting that SolidJS has a meta framework, SolidStart, which makes building web applications faster. SolidStart is a feature-rich and flexible framework for creating cutting-edge web apps using SolidJS. Developers looking to develop complex applications fast and effectively without sacrificing maintainability or scalability will find its feature set quite extensive and its API user-friendly. SolidStart helps build web applications in Solid.
In conclusion, SolidJS is a powerful and effective library that empowers programmers to create efficient and user-friendly web applications. You have covered every crucial SolidJS topic in this practical guide, from project setup through component creation, styling, and state management. Moreover, you have examined how to handle events, convey data between components, fetch data from a remote server, and best practices for optimization.
You will learn SolidJS' versatility and power as you continue to explore it and develop more complicated web applications. SolidJS is a valuable addition to your toolkit for web development projects due to its rising popularity and strong community support.
Github repo for the project: https://github.com/bejamas/solid-movie.