The first question is how you want your resource to behave.
Do you want end users to be able to overwrite or override your icons, or do you want to guarantee that they're available? That dictates whether to add them to the SYSTEM collection, or add them in core.
Okay, then you want to add them to system as you are, but note that the system collection only exists in memory - you won't ever see them on disk:
com.inductiveautomation.perspective.gateway.assets.icons.IconManagerImpl#RESOURCE_TYPE is the shared reference; you could construct an equivalent ResourceType if that's not exposed with new ResourceType("com.inductiveautomation.perspective", "icons").
So without knowing offhand what's exposed outside the Perspective module, this should get you there:
ResourceType type = new ResourceType("com.inductiveautomation.perspective", "icons");
String mySvgData = "...";
String fileName = "mySvgData.svg";
JsonObject configObject = new JsonObject();
configObject.addProperty("svgFileName", fileName);
var resource = Resource.newBuilder()
.setResourcePath(type.childPath("myIcons"))
.putData(fileName, mySvgData)
.putData(Resource.DEFAULT_JSON_KEY, configObject.toString())
.build();
context.getConfigurationManager().addSystemResources(List.of(resource));
to create on hand without module a new Custom Icon Repository,
the good practice is to copy another one, change the resource.json, and config.json and svg files and rescan on the gateway ?
Correct. New to 8.3, modules can contribute an entire project, which acts more or less like a 'system' level resource...but it's an entire project, not a piece of one. You should be able to have it participate in inheritance, though.