# Finalizing your plugins

<Callout variant='info'>
This system has been reworked significantly in RRV 8.0.0. If you are using RRV 7.1.4 or below, please see [its documentation](../legacy/finalizing-your-plugins).
</Callout>

For RRV to know how to handle your recipes, you have to create two RRV plugins for your mod, one on the clientside and one on the serverside.

## Server Plugin

<Callout variant='info'>
If you support other recipe viewers that require synchronizing your mod's recipes (e.g. JEI), you can skip this step and synchronize your recipes via standard [Fabric](https://docs.fabricmc.net/develop/custom-recipe-types#recipe-synchronization)/[NeoForge](https://docs.neoforged.net/docs/resources/server/recipes/#client-side-recipes) APIs which will allow your mod to work with both recipe viewers as long as one is on the server.
</Callout>

For RRV to know how to synchronize your recipes from the server to the client, you have to synchronize your mod's recipes from the server to the client. This can be done at any point, but to guarantee things load at the right time you can do this in a serverside RRV plugin.
This is done by creating a class implementing `ReliableRecipeViewerPlugin`:

In your main plugin, you must call `ServerRecipeManager.synchronizeRecipeType` with your recipe serializer and recipe type. This will automatically be supplied to NeoForge and Fabric's APIs when they request them.

```java
public class ExampleModIntegration implements ReliableRecipeViewerPlugin {
    @Override
    public void onIntegrationInitialize() {
        // Here, you can tell the server to synchronize your mod's recipes to the client. In this example, we're using the server recipe manager to synchronize recipes for an example mod's upgrading recipe type.
        ServerRecipeManager.INSTANCE.synchronizeRecipeType(ExampleModRecipes.UPGRADING_RECIPE_SERIALIZER, ExampleModRecipes.UPGRADING_RECIPE_TYPE);
    }
}
```

Don't forget to add it as an entrypoint to your mod.

### Fabric (fabric.mod.json)

```json
{
...,
	"entrypoints": {
        ...,
		"rrv": [
			"com.example.docs.rrv.ExampleModRecipeViewerIntegration"
		]
	},
...
}
```

### NeoForge (neoforge.mods.toml)

```toml
[[mods]]
modId = "example_mod"
rrv = "com.example.docs.rrv.ExampleModRecipeViewerIntegration"
```

## Client Plugin

For RRV to know how to convert your mod's recipes into client recipes, you also have to create a RRV client plugin for your mod.
This is done by creating a class implementing `ReliableRecipeViewerClientPlugin`:

In your client plugin, you must call `ItemView.addClientRecipeProvider()` and provide a list of `ReliableClientRecipes` for the mod to show. To create a list from vanilla recipes, use `ClientRecipeManager.getRecipesForType` to query the synchronized recipes for your mod's recipe type. You can also add client recipes for vanilla recipe types (like hardcoded crafting recipes) via this event if needed.

```java
public class ExampleModClientIntegration implements ReliableRecipeViewerClientPlugin {
    @Override
    public void onIntegrationInitialize() {
        //For the client
        ItemView.addClientRecipeProvider(recipeList -> { // provides a list of `ReliableClientRecipe`s to add to
            // Upgrading
            ClientRecipeManager.INSTANCE.getRecipesForType(ExampleModRecipes.UPGRADING_RECIPE_TYPE).forEach(upgradingRecipeHolder -> { // provides a list of `RecipeHolder<UpgradingRecipe>`s for you to convert
                UpgradingRecipe recipe = upgradingRecipeHolder.value();
                recipeList.add(new UpgradingClientRecipe(recipe.getBaseItem(), recipe.getUpgradeItem(), recipe.getResult()));
            });
      });
    }
}
```

Don't forget to add it as an entrypoint to your mod.

### Fabric (fabric.mod.json)

```json
{
...,
	"entrypoints": {
        ...,
		"rrv_client": [
			"com.example.docs.rrv.ExampleModRecipeViewerClientIntegration"
		]
	},
...
}
```

### NeoForge (neoforge.mods.toml)

```toml
[[mods]]
modId = "example_mod"
rrv_client = "com.example.docs.rrv.ExampleModRecipeViewerClientIntegration"
```
