When creating a custom package, should asmdef references and package dependencies be the same thing?

Hey all, I’m diving into the world of creating custom packages and have run into a bit of confusion. From what I see, when creating a custom package you need to create a package.json file, as well as an asmdef asset for your package to be imported properly. In the package.json file, you need to list the other packages your package depends on (dependencies) which makes sense, but then when I create an asmdef asset it wants me to include all the other asmdef files my scripts use.

To me these seem like the same thing, like I put TextMeshPro in the package.json dependencies, then I need to add the TextMeshPro asmdef to my asmdef references. I’m fine updating it in both places, but I guess I’m wondering should the package.json and asmdef file be roughly the same thing? A related question, does the naming of the asmdef matter? Does it need to align with the namespace you’re using or your package name?

Sorry if this is a basic question, but I couldn’t find a definitive answer.

The dependencies in package.json are the packages that are required for your package to run. However, you may have optional dependencies or support for other packages.

Namely your assembly definition can be set up to reference certain assemblies, and conditionally compile code only if they’re present.

You can read about it here: Unity - Manual: Assembly definitions

In basic situations, your package.json dependencies and assembly definition references will probably look the same. But they can also be different.

1 Like

I see, thanks! I guess my follow-up is what do each of these do when imported into a new project? Like what if it’s missing one of the references in the asmdef, or one of the dependencies in package.json?

what do each of these do when imported into a new project?

Dependencies on a package.json, are meant to be resolved by the PackageManager

. If propperly configured, when installing a package that depends on other packages, those dependencies will be installed along with the package:

eg: You have “MyCustomPackage” that depends on “Unity.VisualEffectGraph” package. When installing “MyCustomPackage” the package manager will also download and install “Unity.VisualEffectGraph” (if its has not already been added). You also have versioning syntax that allows to specify compatible version ranges for dependencies.

On the other side, for an Asmdef, you are directly telling you package code Assembly, which other Assemblies it needs for it to compile propperly. Those are not managed or auto-imported by anything, they must be properly setup by you.

eg: using the previous example. If you need to reference code from Unity.VisualEffectGraph in the code of your package, your Asmdef will have referenced the Asmdef inside the Unity.VisualEffectGraph package.

One thing to be carefull here is the “use GUIDs” flag. Normally, Asmdefs inside “Packages/…” will come with no “.meta” files. That means, that the GUID for the referenced Asmdef will be different for each user that uses the package. This is not exactly always the case, for a variety of reasons, but for packages is better practice to never check the “use GUIDs” flag, so it gets serialized by name, instead of by asset guid.

If you are missing a reference inside a Asmdef, and your code is actually using a member of the “missing” assembly, then it will throw an error and wont compile.

On the other side, if a package dependency is missing or cannot be resolved, i dont remember if it may not let you install the package, or maybe install it but depending on “what” is missing, a variety of errors could happen. (you could have a package setup as a dependency, but neither your code nor any asset is directly using it, so it may not give any errors, this really depends on the case)

A related question, does the naming of the asmdef matter? Does it need to align with the namespace you’re using or your package name?

Ideally YES. This is more for debug & organization purposes. but it is usefull that your Asmdef asset name, is exactly the same name as the “Name” field.
It is also recommended to have a “Root Namespace” also properly setup, but it’s currently just used when manually creating a new Script on the Editor. The template used for the new script will automatically have the root namespace of its containing assembly .

1 Like

Whoa, very interesting, thanks! One last question about the asmdef… Does adding something to the asmdef references automatically include it with your package, or will it need to be added in the destination project as well? From your answer it sounds like the latter, and that your package will throw errors when imported if something is missing?

So then it sounds like your asmdef has no real “power”, it just tells your package what to look for when imported into a new project. And the role of the package.json dependencies is to ensure that anything it will need is downloaded?

It does not, Asmdef are “code-only”. They do not know anything about packages, assets, or anything, and are only used for compilation.

So then it sounds like your asmdef has no real “power”, it just tells your package what to look for when imported into a new project. And the role of the package.json dependencies is to ensure that anything it will need is downloaded?

Asmdef are the “Unity-way” of managing code dependencies. They fill the role of the <Reference> xml tag in a classical “.csproj”. But they are not aware of nothing package/asset related.

Take into account that a single package, may have multiple Asmdefs (the Runtime asmdef, an Editor-only asmdef, maybe a Tests asmdef) each with different code-dependencies. But all contained within the same package in different folders

If you want anything asset/package related to be included along with your package, then you will always be talking about the package manifest (package.json)