# Manually set up your project to use Vite.js

{% callout type="note" title="Use our generator!" %}
It is recommended that you use the [`@nrwl/vite:configuration`](/packages/vite/generators/configuration) generator to do convert an existing project to use [Vite](https://vitejs.dev/).
{% /callout %}

You can use the `@nrwl/vite:dev-server`,`@nrwl/vite:build` and `@nrwl/vite:test` executors to serve, build and test your project using [Vite](https://vitejs.dev/) and [Vitest](https://vitest.dev/). To do this, you need to make a few adjustments to your project. It is recommended that you use the [`@nrwl/vite:configuration`](/packages/vite/generators/configuration) generator to do this, but you can also do it manually.

A reason you may need to do this manually, is if our generator does not support conversion for your project, or if you want to experiment with custom options.

The list of steps below assumes that your project can be converted to use the `@nrwl/vite` executors. However, if it's not supported by the [`@nrwl/vite:configuration`](/packages/vite/generators/configuration) generator, it's likely that your project will not work as expected when converted. So, proceed with caution and always commit your code before making any changes.

## 1. Change the executors in your `project.json`

### The `serve` target

This applies to applications, not libraries.

In your app's `project.json` file, change the executor of your `serve` target to use `@nrwl/vite:dev-server` and set it up with the following options:

```json
//...
"my-app": {
    "targets": {
        //...
        "serve": {
            "executor": "@nrwl/vite:dev-server",
            "defaultConfiguration": "development",
            "options": {
                "buildTarget": "my-app:build",
            },
            "configurations": {
                ...
            }
        },
    }
}
```

{% callout type="note" title="Other options" %}
Any extra options that you may need to add to your server's configuration can be added in your project's `vite.config.ts` file. You can find all the options that are supported in the [Vite.js documentation](https://vitejs.dev/config/). You can see which of these options you can add in your `project.json` in the [`@nrwl/vite:dev-server`](/packages/vite/executors/dev-server#options) documentation.
{% /callout %}

### The `build` target

In your project's `project.json` file, change the executor of your `build` target to use `@nrwl/vite:build` and set it up with the following options:

```json
//...
"my-app": {
    "targets": {
        //...
        "build": {
        "executor": "@nrwl/vite:build",
        ...
        "options": {
            "outputPath": "dist/apps/my-app"
        },
        "configurations": {
                ...
            }
        },
    }
}
```

{% callout type="note" title="Other options" %}
You can specify more options in the `vite.config.ts` file (see **Step 2** below).
{% /callout %}

## 2. Configure Vite.js

### TypeScript paths

You need to use the [`vite-tsconfig-paths` plugin](https://www.npmjs.com/package/vite-tsconfig-paths) to make sure that your TypeScript paths are resolved correctly in your monorepo.

### React plugin

If you are using React, you need to use the [`@vitejs/plugin-react` plugin](https://www.npmjs.com/package/@vitejs/plugin-react).

### How your `vite.config.ts` looks like

Add a `vite.config.ts` file to the root of your project. If you are not using React, you can skip adding the `react` plugin, of course.

```ts {% fileName="apps/my-app/vite.config.ts" %}
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import ViteTsConfigPathsPlugin from 'vite-tsconfig-paths';

export default defineConfig({
  plugins: [
    react(),
    ViteTsConfigPathsPlugin({
      root: '../../',
    }),
  ],
});
```

If you are converting a library (rather than an application) to use vite, your `vite.config.ts` file should look like this:

```ts {% fileName="libs/my-lib/vite.config.ts" %}
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import viteTsConfigPaths from 'vite-tsconfig-paths';
import dts from 'vite-plugin-dts';
import { join } from 'path';

export default defineConfig({
  plugins: [
    dts({
      tsConfigFilePath: join(__dirname, 'tsconfig.lib.json'),
      // Faster builds by skipping tests. Set this to false to enable type checking.
      skipDiagnostics: true,
    }),
    react(),
    viteTsConfigPaths({
      root: '../../../',
    }),
  ],

  // Configuration for building your library.
  // See: https://vitejs.dev/guide/build.html#library-mode
  build: {
    lib: {
      // Could also be a dictionary or array of multiple entry points.
      entry: 'src/index.ts',
      name: 'pure-libs-rlv1',
      fileName: 'index',
      // Change this to the formats you want to support.
      // Don't forgot to update your package.json as well.
      formats: ['es', 'cjs'],
    },
    rollupOptions: {
      // External packages that should not be bundled into your library.
      external: ['react', 'react-dom', 'react/jsx-runtime'],
    },
  },
});
```

{% callout type="note" title="The `root` path" %}
Make sure the `root` path in the `ViteTsConfigPathsPlugin` options is correct. It should be the path to the root of your workspace.
{% /callout %}

In that config file, you can configure Vite.js as you would normally do. For more information, see the [Vite.js documentation](https://vitejs.dev/config/).

## 3. Move `index.html` and point it to your app's entrypoint

This applies to applications, not libraries.

First of all, move your `index.html` file to the root of your app (e.g. from `apps/my-app/src/index.html` to `apps/my-app/index.html`).

Then, add a module `script` tag pointing to the `main.tsx` (or `main.ts`) file of your app:

```html {% fileName="apps/my-app/index.html" %}
...
  <body>
    <div id="root"></div>
    <script type="module" src="src/main.tsx"></script>
  </body>
</html>
```

## 4. Add a `public` folder

You can add a `public` folder to the root of your project. You can read more about the public folder in the [Vite.js documentation](https://vitejs.dev/guide/assets.html#the-public-directory).

```treeview
myorg/
├── apps/
│   ├── my-app/
│   │   ├── src/
│   │   │   ├── app/
│   │   │   ├── assets/
│   │   │   ├── ...
│   │   │   └── main.tsx
│   │   ├── index.html
│   │   ├── public/
| . | . |   ├── favicon.ico
│   │   │   └── my-page.md
│   │   ├── project.json
│   │   ├── ...
│   │   ├── tsconfig.app.json
│   │   ├── tsconfig.json
│   │   └── tsconfig.spec.json
```

You can use the `public` folder to store static **assets**, such as images, fonts, and so on. You can also use it to store Markdown files, which you can then import in your app and use as a source of content.

## 5. Adjust your project's tsconfig.json

Change your app's `tsconfig.json` (e.g. `apps/my-app/tsconfig.json`) `compilerOptions` to the following:

### For React apps

```json {% fileName="apps/my-app/tsconfig.json" %}
...
  "compilerOptions": {
    "jsx": "react-jsx",
    "allowJs": false,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "lib": ["DOM", "DOM.Iterable", "ESNext"],
    "module": "ESNext",
    "moduleResolution": "Node",
    "noEmit": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strict": true,
    "target": "ESNext",
    "types": ["vite/client"],
    "useDefineForClassFields": true
  },
...
```

### For Web apps

```json {% fileName="apps/my-app/tsconfig.json" %}
...
  "compilerOptions": {
    "target": "ESNext",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ESNext", "DOM"],
    "moduleResolution": "Node",
    "strict": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "esModuleInterop": true,
    "noEmit": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "skipLibCheck": true,
    "types": ["vite/client"]
  },
  "include": ["src"],
...
```

You can read more about the TypeScript compiler options in the [Vite.js documentation](https://vitejs.dev/guide/features.html#typescript-compiler-options).

## 6. Use Vite.js

Now you can finally serve and build your app using Vite.js:

### Serve the app

```bash
nx serve my-app
```

or

```bash
nx run my-app:serve
```

Now, visit [http://localhost:4200](http://localhost:4200) to see your app running!

### Build the app

```bash
nx build my-app
```

or

```bash
nx run my-app:build
```
