# Quick Start: LWR on Node.js

New to LWR? Let's walk through how to build a simple static website in your local environment using LWR on Node.js.

## Install Node

[Node.js](https://nodejs.org/en/) is a free, open source tool that lets you run and develop JavaScript applications. Using LWR **on** Node.js means running LWR inside a Node.js runtime.

Applications developed using Node.js are cross-platform compatible, so they're supported by multiple operating systems (like MacOS, Windows, and Linux). Node.js developers can use JavaScript for both frontend and backend development.

Before you can start your first LWR on Node.js project, [install the latest recommended version of Node.js](https://nodejs.org/).

1. Click the `[Version Number] LTS` button to start downloading Node.js. The button should also say `Recommended For Most Users`.
2. To start the installation process, open your Downloads folder and click the `node-VersionNumber` file (for Windows users) or package (for Mac users) that you just downloaded.

## Create Your First Project

Node.js gives you access to a huge database of packages that you can install in your applications. For this project, you'll use the Node Package Manager (NPM) to set up a simple site template from the `create-lwr` package. Don't worry about how to set up NPM! When you installed Node.js on your computer earlier, you also installed NPM.

Let's review the basics of NPM:

- A **package** is a directory of files.
- A **module** is a JavaScript file inside of a package.
- To install a package in an application, run an `npm` command in a terminal program.
- Some developers use `yarn` commands instead to install packages. We're only going to use `npm` commands because you already have it installed on your machine.

Now you're ready to use NPM to create this project.

:::important
If you previously installed `create-lwr` globally, first uninstall the package by running `npm uninstall -g create-lwr` or `yarn global remove create-lwr`, then complete the following steps. For more information about this package, see [NPM: create-lwr](https://www.npmjs.com/package/create-lwr).
:::

1. In a terminal program, run `npm init lwr@latest`
2. For **Project name**, enter *StaticSite*.
3. Accept the generated package name by pressing the **Enter** key.
4. For **Select a type of project**, accept the default, *Static Site*.
5. For **Select a variant**, accept the default, *Markdown Static Site*.

Just like that, you've scaffolded your first project!

Now, run these three commands to start a live preview of your new site.

```bash
cd StaticSite
npm install
npm run dev
```

You can see your live site preview in your browser on your [localhost](http://localhost:3000/).

![Static Site output](https://a.sfdcstatic.com/developer-website/sfdocs/lwr-node/media/static-site-output.png)

:::tip
Want to explore all of the packages that you can install in a Node.js project? Check out the [NPM Registry](https://www.npmjs.com/) to explore free and paid libraries for your applications.
:::

### Installing vs Initializing a Package

Did you notice that the `create-lwr` package page says you can **install** `create-lwr` by running `npm i create-lwr` in your terminal? Installing and initializing a package are two different actions.

| `npm i package-name`                                                                                                                                                                         | `npm init package-name`                                                                                                                                   |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| This command **installs** a package.                                                                                                                                                         | This command **initializes** a package.                                                                                                                   |
| Running `npm i create-lwr` only installs the `create-lwr` package on your machine. To create the LWR sample site from that package, you have to run `create-lwr` in your terminal afterward. | We recommend scaffolding your project with the `npm init lwr@latest` command because it installs and creates the `create-lwr` sample project in one step. |

If you're wondering exactly what the `npm init lwr@latest` command does, let's break it down:

- `npm init` tells your machine to initialize a new project. It also creates a new package.json file inside of your project directory. This is an important file that handles information about dependencies (like packages) for your project.
- `lwr` is the package you're telling NPM to initialize. This package scaffolds a sample site from the `create-lwr` package.
- The `@latest` suffix tells NPM to install the latest version of the package.

## Deploy to Heroku

Are you a [Heroku developer](https://devcenter.heroku.com/)? Now that you have your static site up and running, deploying to Heroku is a breeze. Heroku uses [the preset start script](https://devcenter.heroku.com/articles/node-best-practices#hook-things-up) in your project's `package.json` file, and LWR serves the app on Heroku in the same way as it does locally. See [Deploying with Git](https://devcenter.heroku.com/articles/git#deploy-your-code) or the [Deployment](https://devcenter.heroku.com/categories/deployment) category in the Heroku Dev Center for more deployment options.

## Set the LWR Server Modes

If you're getting the idea that LWR projects are standard NPM packages, you're right. You can use commands with LWR from typical package manager toolchains like NPM.

:::tip
If you run into errors or have a stale project, try the command `npm run clean`. It removes the build directory and file cache.
:::

For example, using [NPM](https://npmjs.com/), you can run your LWR application in several different modes.

| MODE        | Start Command                      | Module Format | File Watch | Bundling | Minification |
| ----------- | ---------------------------------- | ------------- | ---------- | -------- | ------------ |
| dev         | `npm run dev`                      | ESM           | ✅          | 🚫       | 🚫           |
| prod        | `npm run start`                    | ESM           | 🚫         | ✅        | ✅            |
| compat      | `npm run dev --mode compat`        | AMD           | ✅          | 🚫       | 🚫           |
| prod-compat | `npm run start --mode prod-compat` | AMD           | 🚫         | ✅        | ✅            |

**dev**

Running LWR in `dev` mode uses hot module reloading for easier debugging, so when you change a component in one place it updates immediately. In `dev` mode, the server registers all file paths and watches them individually.

**prod**

When you run in `prod` mode, [LWR bundles](/docs/platform/lwr/guide/lwr-configure-project.md#configure-bundles) modules before sending them to the client. This bundling reduces the number of HTTP requests to the server.

**compat**

By default, the LWR server formats modules in the [ECMAScript format](https://nodejs.org/api/esm.html#modules-ecmascript-modules) or “ESM”. However, some browsers don't support ESM semantics. When you run your application in `compat` mode, LWR uses a custom module loader, and the modules are formatted as [AMD-compliant](https://en.wikipedia.org/wiki/Asynchronous_module_definition) JavaScript resources.

**prod-compat**

A production version of compatibility mode. For `prod-compat`, as with `prod` mode, LWR uses [bundling](/docs/platform/lwr/guide/lwr-configure-project.md#configure-bundles) and minification for efficiency. And, as in `compat` mode, modules are formatted as [AMD-compliant](https://en.wikipedia.org/wiki/Asynchronous_module_definition) resources. |

## It's Simple to Be Sophisticated

LWR is built with customization and extensibility in mind. You can use LWR for everything from static sites to SPAs (single page applications).

Ready to get going? Before we move on, let's review some of the key files in the static site project you just built and their capabilities:

- `lwr.config.json`: With this file you have a variety of options for project configuration, including routing, directory locations, and server configuration. Find out more in [Configure Your LWR Project.](/docs/platform/lwr/guide/lwr-configure-project.md)
- `package.json`: Here you can add dependencies to your project or customize LWR’s module support. Check out [Configure Packages and Modules](/docs/platform/lwr/guide/lwr-packages-modules.md) for more details.
- `src/layouts/main_layout.njk`: The scaffolding for your static site contains a website layout using the [Nunjucks](https://mozilla.github.io/nunjucks/templating.html) templating language. Learn about [LWR layouts and templating.](/docs/platform/lwr/guide/lwr-templates.md)
- `src/content`: The site is using [Markdown](https://daringfireball.net/projects/markdown/) syntax for the content templates for the **Home** and **About** pages. Markdown is easy and fast to use and read, and there are many resources and cheatsheets available.

:::tip
LWR supports the following languages for templating:

- [HTML](https://en.wikipedia.org/wiki/HTML)
- [Markdown](https://www.markdownguide.org/)
- [Nunjucks](https://mozilla.github.io/nunjucks/)
:::

## Next Steps

We hope that your static site gives you a glimpse of the simplicity and flexibility of LWR. Want to do more? You can start by reading up on [LWR content and layout templates](/docs/platform/lwr/guide/lwr-templates.md) and [routing](/docs/platform/lwr/guide/lwr-routing.md).
