# Development setup

For developers

This article takes you from an empty machine to a GrandNode storefront running from source in your IDE, with breakpoints working in core code and in plugins. Only two things are required: the .NET SDK and a MongoDB server. Node.js is needed only when you change frontend sources.

### Prerequisites

| Tool | Version | Needed for |
|---|---|---|
| .NET SDK | 10\.0 — the exact feature band is pinned in `global.json` | building and running everything |
| MongoDB | 4\.0 or newer | the database: a local server, a Docker container or a MongoDB Atlas cluster |
| Node.js and npm | 20 LTS or newer | only when you change the storefront (`vueapp`) or the panel frontend (`adminapp`) |
| IDE | Visual Studio, JetBrains Rider or VS Code | optional |

The quickest MongoDB for development is a container:

```
docker run -d -p 127.0.0.1:27017:27017 --name mongodb mongo
```

### Clone and build

1. Clone the repository. `develop` is the integration branch where new work lands; `main` holds the latest stable release.
   ```
   git clone https://github.com/grandnode/grandnode2.git
   cd grandnode2
   git checkout develop
   ```
2. Restore and build the whole solution:
   ```
   dotnet restore GrandNode.slnx
   dotnet build GrandNode.slnx
   ```

Building the solution is important the first time. `Grand.Web` does not reference the modules and plugins; each of them copies itself into `src/Web/Grand.Web/Modules` or `src/Web/Grand.Web/Plugins` when it is built. After one full build you can start the web project on its own.

### Run

```
dotnet run --project src/Web/Grand.Web
```

The Kestrel launch profile listens on `https://localhost:5001` and `http://localhost:5000`; the IIS Express profile uses `https://localhost:44350`. Both profiles set `ASPNETCORE_ENVIRONMENT=Development`. Keep it that way when you start the app another way: without it the static web assets manifest is not used, files under `_content/` return 404 and the admin panel loads without CSS and JavaScript.

### First run: the installer

On the first run the application redirects to `/install`. Enter the MongoDB connection string, for example `mongodb://localhost/grandnode`, the administrator e-mail and password, and choose whether to load the sample data. The installer writes the connection string to `src/Web/Grand.Web/App_Data/Settings.cfg`, which git ignores. To start over against a fresh database, stop the app, delete that file and run again.

### Configuration

Runtime configuration lives in `src/Web/Grand.Web/App_Data/appsettings.json`. Any value can be overridden with an environment variable using a double underscore for nesting, for example `FeatureManagement__Grand.Module.Api=true` or `Redis__RedisPubSubEnabled=true`. Sections you will meet as a developer:

| Section | What it does |
|---|---|
| `FeatureManagement` | Turns modules on or off: Installer, Migration, ScheduledTasks and Api (the API is off by default). |
| `BackendAPI`, `FrontendAPI` | JWT settings for the REST API — see [The REST API](https://grandnode.com/developers-rest-api). |
| `Redis` | Cache synchronisation between instances and data-protection key storage. |
| `Extensions` | Plugin loading options: `PluginSkipLoadingPattern`, `DisableUploadExtensions`, shadow copying and Roslyn scripts. |

### Debugging

- Set **Grand.Web** as the startup project and press F5. Breakpoints in core, business and web projects work immediately.
- Breakpoints in a plugin work as long as the plugin was built in the same configuration (Debug) — its symbols are copied next to the DLL in `Grand.Web/Plugins/<SystemName>`.
- **Plugin views are compiled into the plugin DLL.** After editing a `.cshtml` file in a plugin or theme, rebuild that plugin (`dotnet build src/Plugins/Theme.Modern`) and restart the site. Razor runtime compilation covers only `Grand.Web`'s own views. Stop the site before rebuilding a plugin, or the build fails on a locked DLL.
- For a multi-instance setup with Redis, run the Aspire host in `src/Aspire/Aspire.AppHost`: it starts MongoDB and Redis in containers and two replicas of the web app that share one database.

### Running the tests

```
dotnet test src/Tests/Grand.Business.Catalog.Tests
dotnet test GrandNode.slnx
```

Tests use MSTest and Moq. Run the project closest to your change while iterating and the whole solution before you open a pull request.

### Frontend bundles

The storefront UI (Vue 3, Bootstrap 5) lives in `src/Web/Grand.Web/vueapp`; the panels are built from `src/Web/Grand.SharedUIResources/adminapp`. The built bundles are committed to the repository, which is why you can run the shop without Node. If you change anything under `vueapp/src` or `wwwroot/theme/css`, rebuild and commit the bundles with the source change:

```
cd src/Web/Grand.Web/vueapp
npm install
npm run build
```

### Running the Docker image instead

If you only need a running instance to develop against, for example for API work, use the published image:

```
docker run -d -p 127.0.0.1:27017:27017 --name mongodb mongo
docker run -d -p 80:8080 --name grandnode2 --link mongodb:mongo grandnode/grandnode2
```

### Tips and common mistakes

- A plugin you just added does not appear: it was not built, or its output path does not point into `Grand.Web/Plugins`.
- The admin panel has no styles: `ASPNETCORE_ENVIRONMENT` is not `Development`.
- A view change in a plugin does nothing: the plugin was not rebuilt.

### Related

- [Architecture overview](https://grandnode.com/developers-architecture-overview)
- [Contributing](https://grandnode.com/developers-contributing)
- Installing for production: [Getting started](https://grandnode.com/docs-getting-started)

- [Web page](https://grandnode.com/developers-development-setup)
