# Build A Fullstack App with Remix, Prisma & MongoDB: Project Setup URL: https://www.prisma.io/blog/fullstack-remix-prisma-mongodb-1-7d0bftxbmb6r Published: 2022-04-25 Authors: Sabin Adams Tags: education Series: Build A Fullstack App with Remix, Prisma & MongoDB Description: Learn how to build and deploy a fullstack application using Remix, Prisma, and MongoDB. In this article, we will be setting up our project, the MongoDB instance, Prisma, and begin modeling out some of our data for the next section of this series. Welcome to the first article in this series, where you will take a look at how to build a full-stack application from the ground up using MongoDB, Prisma, and Remix! In this article, you will be setting up your project, the MongoDB instance, Prisma, and begin modeling out some of our data for the next section of this series. ## Table Of Contents [#table-of-contents] * [Introduction](#introduction) * [Technologies you will use](#technologies-we-will-use) * [What this series covers](#what-this-series-covers) * [What you will learn today](#what-you-will-learn-today) * [Prerequisites](#prerequisites) * [Assumed knowledge](#assumed-knowledge) * [Development environment](#development-environment) * [Generate the Remix application](#generate-the-remix-application) * [Take a look at the starter project](#take-a-look-at-the-starter-project) * [Set up TailwindCSS](#set-up-tailwindcss) * [Create a MongoDB instance](#create-a-mongodb-instance) * [Set up Prisma](#set-up-prisma) * [Initialize and configure Prisma](#initialize-and-configure-prisma) * [Set your environment variable](#set-your-environment-variable) * [Model the data](#model-the-data) * [Push schema changes](#push-schema-changes) * [Summary & What's next](#summary--whats-next) [Watch the video on YouTube](https://www.youtube.com/watch?v=4tXGRe5CDDg) ## Introduction [#introduction] The goal of this series is to take an in-depth look at how to start, develop and deploy an application using the technologies mentioned below and hopefully highlight just how easy it is to do so with the rich feature sets these tools provide! By the end of this series, you will have built and deployed an application called "Kudos", a site where users can create an account, log in, and give kudos to other users of the site. It will end up looking something like this:  ### Technologies we will use [#technologies-we-will-use] Throughout this series you will be using the following tools to build this application: * [MongoDB](https://www.mongodb.com/) as the database * [Prisma](https://www.prisma.io/) as your Object Document Mapper (ODM) * [Remix](https://remix.run/) as the React framework * [TailwindCSS](https://tailwindcss.com/) for styling the application * [AWS](https://aws.amazon.com/) S3 for storing user-uploaded images * [Vercel](https://vercel.com/) for deploying the application ### What this series covers [#what-this-series-covers] You will be diving into every aspect of building this application, including: * Database configuration * Data modeling * Authentication with session-based auth * Create, Read, Update and Delete (CRUD) operations, along with the filtering and sorting of data using Prisma * Image uploads using AWS S3 * Deploying to Vercel ### What you will learn today [#what-you-will-learn-today] In this first article, you will go through the process of starting up a Remix project, setting up a MongoDB database using Mongo's [Atlas](https://www.mongodb.com/atlas/database) platform, installing Prisma, and beginning to model out some of the data for the next section of this series. By the end, you should have a strong foundation to continue building the rest of your application on. ## Prerequisites [#prerequisites] ### Assumed knowledge [#assumed-knowledge] While this series is meant to guide you through the development of a fullstack application, the following previous knowledge will be assumed: * Experience working in a JavaScript ecosystem * Experience with [React](https://reactjs.org/), as Remix is a framework built on React * A basic understanding of "schemaless" database concepts, specifically with MongoDB * A basic understanding of working with Git ### Development environment [#development-environment] In order to follow along with the examples provided, you will be expected to ... * ... have [Node.js](https://nodejs.org) installed. * ... have [Git](https://git-scm.com/downloads) installed. * ... have the [TailwindCSS VSCode Extension](https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss) installed. *(optional)* * ... have the [Prisma VSCode Extension](https://marketplace.visualstudio.com/items?itemName=Prisma.prisma) installed. *(optional)* > **Note**: The optional extensions add some really nice intellisense and syntax highlighting for Tailwind and Prisma. ## Generate the Remix application [#generate-the-remix-application] The very first thing you will need to do is initialize a Remix application. [Remix](https://remix.run/) is a fullstack web framework that allows you to easily build entire React applications without having to worry about the application's infrastructure. It helps you to focus on developing your applications rather than spending time managing multiple areas of the stack separately and orchestrating their interactions. It also provides a nice set of tools you will make use of to aid in otherwise tedious tasks. To start off a Remix project, run the following command in a location where you would like this project to live: ```shell npx create-remix@latest kudos ``` This will scaffold a starter project for you and ask you a couple of questions. Choose the following options to let Remix know you want a blank project using TypeScript and you intend to deploy it to Vercel. * What type of app do you want to create? **Just the basics** * Where do you want to deploy? Choose Remix if you're unsure, it's easy to change deployment targets. **Vercel** * TypeScript or JavaScript? **TypeScript** * Do you want me to run npm install? **Yes** ### Take a look at the starter project [#take-a-look-at-the-starter-project] Once the project is set up, go ahead and pop it open by either opening the project in your code editor or by running the command `code .` within that folder in your terminal if you are using [VSCode's CLI](https://code.visualstudio.com/docs/editor/command-line). You will see the generated boilerplate project with a file structure that looks like this: ``` │── app │ ├── entry.client.tsx │ ├── entry.server.tsx │ ├── root.tsx │ └── routes │ ├── README.md │ └── index.tsx ├── node_modules ├── package-lock.json ├── package.json ├── public │ └── favicon.ico ├── remix.config.js ├── remix.env.d.ts ├── server.js ├── tsconfig.json ├── README.md └── vercel.json ``` For the majority of this series, you will be working within the `app` directory, which will hold all of the custom code for this application. Any file within `./app/routes` will be turned into a route. For example, assuming your application is running on `localhost:3000`, the `./app/routes/index.tsx` file will result in a generated route at `localhost:3000/`. If you were to create another file at `app/routes/home.tsx`, Remix would generate a `localhost:3000/home` route in your site. This is one of the magical pieces of Remix that makes development so easy! Of course, there are a lot more powerful features along with this basic example. If you are curious, check out their [docs](https://remix.run/docs/en/v1/guides/api-routes) on the routing capabilities. > **Note**: You can read more about Remix's routing [here](https://remix.run/docs/en/v1/tutorials/jokes#routes). You will also be using other routing features such as [nested routes](https://remix.run/docs/en/v1/guides/routing#what-are-nested-routes) and [resource routes](https://remix.run/docs/en/v1/guides/resource-routes) later on in the series! If you run this project with the command `npm run dev` and head over to [http://localhost:3000/](http://localhost:3000/), you should see the basic starter application.  Great! Your basic project is started up and Remix has already scaffolded out many of the pieces you would normally have had to set up manually, such as the routing and build process. Now you will move on to setting up TailwindCSS so you can make the application look nice! ## Set up TailwindCSS [#set-up-tailwindcss] [TailwindCSS](https://tailwindcss.com/) provides a robust set of utility classes and functions that will help you quickly build beautiful user interfaces that are easily customizable to fit your custom design needs. You will be making use of TailwindCSS for all of the styling in this application. Tailwind has a great [guide](https://tailwindcss.com/docs/guides/remix) that goes through the steps of configuring it in a Remix project. You will be guided through those steps below: To start things off, there are a few dependencies you will need in order to use Tailwind: ```shell npm install -D tailwindcss postcss autoprefixer concurrently ``` This will install the following development dependencies: * [`tailwindcss`](https://tailwindcss.com/): The command-line interface *(CLI)* that allows you to initialize a Tailwind configuration. * [`postcss`](https://postcss.org/): TailwindCSS is a PostCSS plugin and relies on PostCSS to be built. * [`autoprefixer`](https://www.npmjs.com/package/autoprefixer): A PostCSS plugin used to add browser-specific prefixes to your generated CSS automatically. This is required by TailwindCSS. * [`concurrently`](https://www.npmjs.com/package/concurrently): This allows you to run your Tailwind build process alongside the Remix build process. Once those are installed, you can initialize Tailwind in the project: ```shell npx tailwindcss init -p ``` This will generate two files: * `tailwind.config.js`: This is where you can tweak and extend TailwindCSS. See all of the options [here](https://tailwindcss.com/docs/configuration). * `postcss.config.js`: [PostCSS](https://postcss.org/) is a CSS transpiler. This file is where you can add plugins. When a build is run, Tailwind will scan through the codebase to determine which of its utility classes it needs to bundle into its generated output. You will need to let Tailwind know which files it should look at to determine this. In `tailwind.config.js`, add the following glob pattern to the `content` key: ```js diff // tailwind.config.js module.exports = { content: [ + "./app/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } ``` This will tell Tailwind that any file inside of the `app` folder with the provided extensions should be scanned through for keywords and class names that Tailwind will pick up on to generate its output file. Next, in `package.json` update your `scripts` section to include a build process for Tailwind when the application is built and when the development server runs. Add the following scripts: ```json // package.json { "scripts": { "build": "npm run build:css && remix build", "build:css": "tailwindcss -m -i ./styles/app.css -o app/styles/app.css", "dev": "concurrently \"npm run dev:css\" \"remix dev\"", "dev:css": "tailwindcss -w -i ./styles/app.css -o app/styles/app.css" } } ``` You may notice a few of the scripts are pointing to a file at `./styles/app.css` that does not exist yet. This will be Tailwind's source file when it is built and where you will import the various [functions and directives](https://tailwindcss.com/docs/functions-and-directives) Tailwind will use. Go ahead and create that source file at `./styles/app.css` and add each of Tailwind's [layers](https://tailwindcss.com/docs/adding-custom-styles#using-css-and-layer) using the [`@tailwind`](https://tailwindcss.com/docs/functions-and-directives#tailwind) directive: ```css /* ./styles/app.css */ @tailwind base; @tailwind components; @tailwind utilities; ``` Now when the application is run or built, your `scripts` will also kick off the process to run Tailwind's scanning and building process. The result of this will be outputted into `app/styles/app.css`. That file is what you will import into your Remix application to allow you to use Tailwind in your code! In `app/root.tsx`, import the generated stylesheet and export a [`links`](https://remix.run/docs/en/v1/api/conventions#links) function to let Remix know you have an asset you want to be imported into all of your modules when the application is built: ```tsx // ./app/root.tsx // 1 import type { MetaFunction, LinksFunction } from "@remix-run/node"; // 2 import styles from './styles/app.css'; // ... // 3 export const links: LinksFunction = () => { return [{ rel: 'stylesheet', href: styles }] } // ... ``` The code above will: 1. Import the type for Remix's `links` function. 2. Import the generated stylesheet. 3. Export a function named `links`, which follows a convention Remix picks up on and uses to import assets into all modules. > **Note**: If you had exported a `links` function within an individual route file rather than the `root.tsx` file, it would be load the assets returned on that route only. For more info on asset imports and conventions, check out Remix's [docs](https://remix.run/docs/en/v1/api/conventions#asset-url-imports). Now go into the `./app/routes/index.tsx` file and replace its contents with the following sample to make sure Tailwind is set up correctly: ```tsx // ./app/routes/index.tsx export default function Index() { return (