Building Remix Applications with the MongoDB Stack
Rate this article
The JavaScript ecosystem has stabilized over the years. There isn’t a new framework every other day, but some interesting projects are still emerging. Remix is one of those newer projects that is getting a lot of traction in the developer communities. Remix is based on top of React and lets you use the same code base between your back end and front end. The pages are server-side generated but also dynamically updated without full page reloads. This makes your web application much faster and even lets it run without JavaScript enabled. In this tutorial, you will learn how to use it with MongoDB using the new MongoDB-Remix stack.
For this tutorial, you will need:
- Node.js.
Remix uses stacks of technology to help you get started with your projects. This stack, similar to others provided by the Remix team, includes React, TypeScript, and Tailwind. As for the data persistence layer, it uses MongoDB with the native JavaScript driver.
Start by initializing a new project. This can be done with the
create-remix
tool, which can be launched with npx. Answer the questions, and you will have the basic scaffolding for your project. Notice how we use the --template
parameter to load the MongoDB Remix stack (mongodb-developer/remix
) from Github. The second parameter specifies the folder in which you want to create this project.1 npx create-remix --template mongodb-developer/remix remix-blog
This will start downloading the necessary packages for your application. Once everything is downloaded, you can
cd
into that directory and do a first build.1 cd remix-blog 2 npm run build
You’re almost ready to start your application. Go to your MongoDB Atlas cluster (loaded with the sample data), and get your connection string.
At the root of your project, create a
.env
file with the CONNECTION_STRING
variable, and paste your connection string. Your file should look like this.1 CONNECTION_STRING=mongodb+srv://user:pass@cluster0.abcde.mongodb.net
At this point, you should be able to point your browser to http://localhost:3000 and see the application running.
Voilà! You’ve got a Remix application that connects to your MongoDB database. You can see the movie list, which fetches data from the
sample_mflix
database. Clicking on a movie title will bring you to the movie details page, which shows the plot. You can even add new movies to the collection if you want.You now have a running application, but you will likely want to connect to a database that shows something other than sample data. In this section, we describe the various moving parts of the sample application and how you can edit them for your purposes.
The database connection is handled for you in the
/app/utils/db.server.ts
file. If you’ve used other Remix stacks in the past, you will find this code very familiar. The MongoDB driver used here will manage the pool of connections. The connection string is read from an environment variable, so there isn’t much you need to do here.In the sample code, we connect to the
sample_mflix
database and get the first 10 results from the collection. If you are familiar with Remix, you might already know that the code for this page is located in the /app/routes/movies/index.tsx
file. The sample app uses the default naming convention from the Remix nested routes system.In that file, you will see a loader at the top. This loader is used for the list of movies and the search bar on that page.
1 export async function loader({ request }: LoaderArgs) { 2 const url = new URL(request.url); 3 4 let db = await mongodb.db("sample_mflix"); 5 let collection = await db.collection("movies"); 6 let movies = await collection.find({}).limit(10).toArray(); 7 8 // … 9 10 return json({movies, searchedMovies}); 11 }
You can see that the application connects to the
sample_mflix
database and the movies
collection. From there, it uses the find method to retrieve some records. It queries the collection with an empty/unfiltered request object with a limit of 10 to fetch the databases' first 10 documents. The MongoDB Query API provides many ways to search and retrieve data.You can change these to connect to your own database and see the result. You will also need to change the
MovieComponent
(/app/components/movie.tsx
) to accommodate the documents you fetch from your database.The movie details page can be found in
/app/routes/movies/$movieId.tsx
. In there, you will find similar code, but this time, it uses the findOne method to retrieve only a specific movie.1 export async function loader({ params }: LoaderArgs) { 2 const movieId = params.movieId; 3 4 let db = await mongodb.db("sample_mflix"); 5 let collection = await db.collection("movies"); 6 let movie = await collection.findOne({_id: new ObjectId(movieId)}); 7 8 return json(movie); 9 }
You might have noticed the Add link on the left menu. This lets you create a new document in your collection. The code for adding the document can be found in the
/app/routes/movies/add.tsx
file. In there, you will see an action function. This function will get executed when the form is submitted. This is thanks to the Remix Form component that we use here.1 export async function action({ request }: ActionArgs) { 2 const formData = await request.formData(); 3 const movie = { 4 title: formData.get("title"), 5 year: formData.get("year") 6 } 7 const db = await mongodb.db("sample_mflix"); 8 const collection = await db.collection("movies"); 9 const result = await collection.insertOne(movie); 10 return redirect(`/movies/${result.insertedId}`); 11 }
That’s it! You have a running application and know how to customize it to connect to your database. If you want to learn more about using the native driver, use the link on the left navigation bar of the sample app or go straight to the documentation. Try adding pages to update and delete an entry from your collection. It should be using the same patterns as you see in the template. If you need help with the template, please ask in our community forums; we’ll gladly help.