Project Links
A project link makes Vite’s final output directory appear as one Wallpaper Engine local project:
wallpaperEnginePlugin({ title: 'Night Sky', projectLink: { name: 'night-sky', },});The destination becomes:
<projects/myprojects>/night-sky → <resolved Vite outDir>The plugin prepares or validates the link during a build only when Vite’s final build.write is true. write: false builds do not touch the filesystem link. The target is the final resolved root + build.outDir, not a hard-coded dist directory.
Options
Section titled “Options”interface WallpaperProjectLinkOptions { name: string; projectsDirectory?: string;}nameis the one directory entry created belowprojects/myprojects.projectsDirectoryis an explicit existing absolute directory that should point to Wallpaper Engine’sprojects/myprojects. The plugin validates the path, but cannot prove that it belongs to Wallpaper Engine.
Windows discovery
Section titled “Windows discovery”When projectsDirectory is omitted on Windows, the plugin:
- Collects Steam roots from Windows installation discovery.
- Reads each root’s
steamapps/libraryfolders.vdf. - Looks in every distinct Steam library for
steamapps/common/wallpaper_engine/projects/myprojects. - Resolves matching directories to real paths.
Exactly one match succeeds. No match fails with guidance to set projectsDirectory. Multiple matches fail and list them so the build never guesses which Wallpaper Engine installation to modify.
Automatic discovery is Windows-only. On macOS and Linux, configure an explicit absolute directory.
wallpaperEnginePlugin({ title: 'Night Sky', projectLink: { name: 'night-sky', projectsDirectory: '/absolute/path/to/projects/myprojects', },});Link type by platform
Section titled “Link type by platform”| Platform | Created link |
|---|---|
| Windows | Directory junction |
| Other platforms | Directory symbolic link (type: 'dir') |
The configured projects directory must already exist and be a directory. The plugin does not create or guess a missing parent. It creates the resolved output target directory recursively so the link has a real target before link creation.
Name validation
Section titled “Name validation”projectLink.name must be one non-empty directory name. It rejects:
- Leading or trailing whitespace.
.and...- NUL characters.
/or\path separators.- Non-string or empty values at runtime.
A link name cannot escape the configured projects directory.
Collision and overlap protection
Section titled “Collision and overlap protection”Before creating anything, the plugin rejects a target and destination that are equal or where either contains the other. This prevents recursive build output and cleanup paths.
At the destination:
- No existing path: create the link.
- Existing symbolic link or junction resolving to the same target: succeed without changing it.
- Existing file, real directory, broken link, or link to another target: fail.
Path comparison is case-insensitive on Windows and case-sensitive elsewhere. Real paths are checked so equivalent links remain idempotent.
Filesystem and permission failures include both the intended destination and target. Fix the parent directory, permissions, or existing path; do not bypass the checks by nesting output inside projects/myprojects.
Written-build timing
Section titled “Written-build timing”The link is prepared after Vite resolves configuration and only for a written build. project.json and other assets are then written into the linked target through normal Vite output. A build failure can therefore leave a correctly targeted but incomplete output directory; rerun the build after fixing the error.
The link itself persists across builds, allowing Wallpaper Engine to edit project state in the same output directory. Project Metadata captures that state before Vite cleanup.
Source
Section titled “Source”Discovery, validation, and link creation are implemented in src/plugin/project-link.ts.
Next steps
Section titled “Next steps”Follow the Workshop Workflow for a linked edit/build/publish loop and use Troubleshooting for discovery or collision failures.