How do you share a linked material Library across many users and machines (and push updates)?

Shared Material Library Across a Team – Portable Linking & Remote Asset Libraries

Hi everyone,

We are a small team building an internally used Blender add-on that quite a few people in our company use to create 3D models – with one shared material library. We are stuck on a workflow question and would love to hear how others handle this, or whether we are misusing the system or missing something obvious.

Current Setup

  • Our add-on is distributed automatically to all users through a CI/CD pipeline. It is installed into each user’s AppData folder, so the path is different for every user – it contains the Windows username.
  • The add-on ships a material library (about ~40 materials).
  • The materials are used inside other scene files, which are saved to a separate repo (Git LFS) on the local computer.
  • When we add or change a material asset in our library, we would like that change to be reflected in everyone’s files without having to reapply it.

The Workaround

We link the materials inside the finished scenes, because this is the only way we know to get library updates into existing files.

The problem: the .blend files store the path to the local library file, which for us lives inside the user’s AppData. When someone else on the team opens a scene from the Git repo, the library cannot be found, because their AppData path is different.

As a workaround, our add-on fixes the library paths: whenever Blender opens any file, it rewrites that path to the current user’s own AppData material library. This feels hacky, to say the least.

What We Tried: Remote Asset Libraries

We were initially excited about this feature and built a small proof of concept:

  • generated the listing files
  • hosted the library on cloud storage
  • browsing, applying and thumbnails worked great – nice job there!

However, it does not seem to fit our case:

  • Only Append and Pack are available as import methods; Link is not offered for remote libraries. Append and Pack create copies, so updates would never reach existing 3D models.
  • The downloaded library ends up in a user cache folder in AppData. If we link the materials from there via scripting, we are back to the same problem: the path contains the username and doesn’t work on another computer.

Questions

  1. How is this scenario usually handled in small studios where multiple people work with the same material library on different computers?
  2. Is there a built-in way to make library paths portable between computers that we overlooked (e.g. path variables like %APPDATA%)?
  3. Are there plans for remote asset libraries to support linking, or any other way to update assets that came from a remote asset library?

Thanks in advance – any hints, experiences, or “don’t do it like that – do it this way” stories are very welcome!

I guess my first question would be why isn’t the material library just stored on a single network location and every computer (no matter who logins) links to it from there?

thanks for the quick reply, good question!

We would like to avoid a network share for a few reasons:

  • people work remotely or offline several of us are on laptops, often away from the office network or on VPN - if the library is only on a share, materials go missing as soon as the share cant be reached - this is semi good in my eyes
  • the library file with packed textures on the network share - would results reading it over VPN every time a scene opens - this would be slow i assume (sure it depends on the connection and the share itself and is currently untested!)
  • a handful of the users (but still, we have them) are not even in our Team - we dont have a network share with these users at all (onboarding (these and) new users would have the side effect of the IT having to give them access to the dedicated share)
  • blend files live in a Git LFS repo that everyone clones locally, and our distribution runs through CI/CD - the network share would be an extra piece of infrastructure to maintain(and manage with permissions) just for this one file?

These are the few things which are cons for a network share currently mapped to our specific case - but thanks for your input - i appreciate it!

From my time with windows I remember some comandline to bind/mount a specific directory to a certain drive letter so that your material library could be for example on M:\somepath\ or L:\anotherPath\…

…

Ahh yes it’s called mapping so the command is called subst.. :wink:

subst L: "C:\Documents and Settings\SomeUserName\UserData\somewhere\toLookAt\"

..so if you Assets–folder is under ..\toLookAt\ then you find them in L:\Assets\

..so the ..\SomeUserName\.. maybe different on every machine but for windows (and blender ) it’s always L:\Assets\

(might have changed in recent Windows.. also there is no autoexec.bat or config.whatever any more ??)

Since your scenes already live in a cloned Git LFS repo, one portable arrangement is to keep the canonical material library inside that same movable project tree:

project/Materials/materials.blend
project/Scenes/scene.blend

The scene links to //../Materials/materials.blend. Your existing CI can copy or sync the packed material-library file into Materials in each clone. This keeps offline/local access, without storing the user’s AppData path or adding a load handler. Updates still require the canonical file to be synced locally and the linked library reloaded/reopened; it isn’t a remote-library live-update mechanism.

I tested a small synthetic example in Blender 5.2.2 on macOS: moved the whole project from an Alice directory to a Bob directory, removed Alice’s library, and opened Bob’s scene in a fresh Blender process. The linked material still resolved. Updating the external library from red to green and reloading changed the cube while preserving the linked material and its assignment.

Here is the helper used for the test. Run it in Blender’s Text Editor with your actual directories and filename. The default call only prints matching links; the commented apply call changes link metadata and reloads. It skips nested libraries and does not save or overwrite scene/library files. This test does not validate your Windows CI, nested dependencies, or distribution of updates.

from pathlib import Path
import os
import bpy

def migrate_library(*, current_root, target_root, basename, apply=False):
    if not bpy.data.filepath:
        raise ValueError('Save the scene inside the project first.')
    if Path(basename).name != basename or not basename.endswith('.blend'):
        raise ValueError('basename must be one explicit .blend filename.')
    source_root = Path(current_root).expanduser().resolve()
    destination_root = Path(target_root).expanduser().resolve()
    destination = destination_root / basename
    scene_directory = Path(bpy.data.filepath).resolve().parent
    if not destination.is_file():
        raise FileNotFoundError(str(destination))
    relative_path = '//' + os.path.relpath(destination, scene_directory).replace(os.sep, '/')
    report = []
    for library in tuple(bpy.data.libraries):
        if library.parent is not None:
            report.append({'name': library.name, 'status': 'skip_nested_library'})
            continue
        resolved = Path(bpy.path.abspath(library.filepath)).resolve()
        if resolved.parent != source_root or resolved.name != basename:
            continue
        row = {'name': library.name, 'original_path': library.filepath,
               'proposed_path': relative_path, 'applied': False}
        if apply:
            prior_path = library.filepath
            try:
                library.filepath = relative_path
                library.reload()
                row['applied'] = True
            except Exception:
                library.filepath = prior_path
                library.reload()
                raise
        report.append(row)
    return report

# Set these to your actual existing library directory and new Materials folder:
OLD_ROOT = r'C:\Users\Alice\AppData\your_addon'
NEW_ROOT = r'C:\your_scene_repo\Materials'
NAME = 'materials.blend'
# Audit only. Review the printed matching links first:
print(migrate_library(current_root=OLD_ROOT, target_root=NEW_ROOT, basename=NAME))
# To migrate a COPY of the scene after auditing, uncomment:
# print(migrate_library(current_root=OLD_ROOT, target_root=NEW_ROOT, basename=NAME, apply=True))

Would keeping Materials beside the scene repo work for your layout, or must the only library copy remain inside the installed add-on’s AppData folder?

Funny enough, this would pretty much be the same as my network share, only the mapping is all local. So it doesn’t matter where the actual file is on the local drive (and hence under whatever user name), it’s always linked/accessed via the mapped drive letter on every PC, as in your L:\Assets\ or whatever.

Not so much an issue, there’s startup tasks and the Task Scheduler that one can use to basically run anything (at anytime) and hence do what autoexec.bat and config.sys use to do.