Orchard Core Asset Manager
SkillFiles & storageLets your agent build and manage OrchardCore frontend assets like SCSS, JS, and Vue files.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Orchard Core Asset Manager skill
About this capability
Builds, watches, and manages frontend assets in OrchardCore. Use when modifying SCSS, JS, TS, or Vue files, adding new assets to a module/theme, or troubleshooting build failures. Covers all asset actions (vite, sass, min, copy, parcel, webpack, concat) and the three-tier package structure.
What this skill tells your AI
The instructions your AI receives, as published by orchardcms/orchardcore in .agents/skills/orchardcore-asset-manager/SKILL.md and read by ahel’s review.
Use the Orchard Core Asset Manager for frontend assets in Orchard Core 3.0 modules and themes. It is based on Concurrently, so it can run shell commands as well as Parcel, Vite, Webpack, Sass, minification, concatenation, and copy actions. Definitions live in Assets.json files and the tool uses ES modules (.mjs) for its own configuration.
Scope and transition from Gulp
- This skill covers the framework's development asset pipeline for Orchard Core modules and themes. It does not cover the Media module's runtime media storage or image processing.
- Orchard Core 3.0 introduces the Asset Manager to gradually replace the Gulp pipeline.
- Gulp remains available for backward compatibility while existing projects transition. Use the Asset Manager for new work and migrate a Gulp pipeline when its output and resource references have been verified.
- The Asset Manager builds files into
wwwroot; it does not register those files with Orchard Core's Resource Management system. Keep the existing resource manifest or tag helper registration and point it to the generated files.
Prerequisites and project setup
-
Install the Node.js LTS version required by the repository. For the Orchard Core 3.0 repository, use the version in the root
.node-versionfile (the current documentation specifies Node.js 24.x LTS). -
From the repository root, enable Corepack and install workspace dependencies:
corepack enable yarnVerify that the Yarn version matches the
packageManagervalue in the rootpackage.json. If Node.js came from a distributor without Corepack, install Corepack first withnpm install -g corepack. -
Keep the three package responsibilities separate:
Location Responsibility Root package.jsonYarn workspaces, top-level scripts, general development dependencies, and optional resolutions.scripts/assets-manager/package.jsonAsset Manager CLI and build tools such as Parcel, Vite, Webpack, Sass, and PostCSS Module or theme Assets/package.jsonRuntime frontend dependencies shipped by that module or theme Add a module or theme dependency from its
Assetsdirectory, then runyarnfrom the repository root:cd src/OrchardCore.Modules/YourModule/Assets yarn add your-library cd ../../../../ yarnUpdate the build toolchain only in
.scripts/assets-manager/package.json. Use rootresolutionswhen the workspace must force one version. -
Add
Assets.jsonat the module or theme root. Its paths are relative to that project. Thesourceentry points to an input file or folder, anddestis a folder when the action writes files.
Assets.json
Assets.json is a JSON array of named actions. Names are used by -n filters and tags are used by -t filters.
Parcel
Parcel is the recommended simple starting point because it needs little configuration:
[
{
"action": "parcel",
"name": "your-module",
"source": "Assets/Scripts/app.js",
"dest": "wwwroot/Scripts/your-module",
"tags": ["js", "admin"]
}
]
The source is the Parcel entry point. Set a different dest folder for each Parcel action because the folder is cleaned before a build or watch operation. Parcel can also use bundleEntrypoint to place several applications in the shared output configured by build.config.mjs; when it is used, omit dest.
Parcel creates JavaScript source-map output. Register the minified and non-minified files in the resource manifest, for example SetUrl("~/YourModule/Scripts/app.min.js", "~/YourModule/Scripts/app.js").
Vite
Use Vite when the application needs a Vite configuration, such as a Vue app:
[
{
"action": "vite",
"name": "your-vue-app",
"source": "Assets/vite-project",
"tags": ["admin", "dashboard", "js"]
}
]
source must be the folder containing vite.config.ts or vite.config.js. Configure an absolute output directory in Vite:
import { defineConfig } from "vite";
import path from "node:path";
import { fileURLToPath } from "node:url";
const directory = path.dirname(fileURLToPath(import.meta.url));
export default defineConfig({
build: {
outDir: path.resolve(directory, "../../wwwroot/Scripts/your-app"),
},
});
Do not set build.minify for Asset Manager Vite builds. The Asset Manager injects its orchard-minify plugin for build and watch. It produces a source-map-aware file, a .min.js or .min.css file without a source-map reference, and a map file.
Webpack
Use the Webpack action when the project already has a Webpack configuration:
[
{
"action": "webpack",
"name": "your-webpack-app",
"config": "Assets/webpack.config.js",
"tags": ["js"]
}
]
config points to the webpack.config.js file.
Concurrently run actions
Use run to execute any project command through Concurrently:
[
{
"action": "run",
"name": "your-app",
"source": "Assets/your-app",
"scripts": {
"build": "yarn build",
"watch": "yarn start"
}
}
]
source is the command working directory. The scripts keys must match the pipeline command. For example, yarn build runs each build script. Concurrently retries builds up to three times, which helps reduce transient CI failures.
Copy, min, Sass, and concat
Use copy for files that do not need bundling:
[
{
"action": "copy",
"name": "vendor-bootstrap",
"source": [
"node_modules/bootstrap/dist/css/bootstrap.css",
"node_modules/bootstrap/dist/js/bootstrap.js"
],
"dest": "wwwroot/Vendor/bootstrap",
"tags": ["resources"]
}
]
sourcecan be one path, a glob, or an array of paths and globs.destis always a folder and files are not renamed.copydoes not watch. Abuildcopies files;watchdoes not.minminifies a file or glob into a destination folder.sasstranspiles SCSS into a destination folder.concattakes an array of files and physically joins them in the listed order. It is not a module resolver or bundler.
When copy uses **, the base folder is detected and preserved below dest. Use dryRun on copy or min actions to inspect matched files and destinations before writing output.
For concat sources beginning with node_modules/, resolution uses the workspace root node_modules directory. Keep shared package versions equal, enforce them with root resolutions, use an NPM alias for genuinely different versions, or use a bundler instead:
{
"dependencies": {
"bootstrap": "5.3.8",
"bootstrap-4.6.1": "npm:bootstrap@4.6.1"
}
}
Commands
Run commands from the repository root:
| Command | Use |
|---|---|
yarn build | Build all discovered assets |
yarn build -n your-name | Build one named action |
yarn build -n first,second | Build multiple named actions |
yarn build -t admin | Build actions with a tag |
yarn watch -n your-name | Rebuild a named action when source files change |
yarn host -n your-name | Start a bundler development server |
yarn copy -n your-name | Run copy actions |
yarn dry-run -n your-name | Preview copy, min, and concat actions without writing files |
yarn clean | Clean generated folders and the Parcel cache |
Use -n, --name, or --names for names and -t, --tag, or --tags for tags. watch does not copy files, so run yarn build after changing a copy action. The Asset Manager can also run from Visual Studio Task Runner Explorer, and the Asset Bundler Tool Debug VS Code launcher is available in the Orchard Core repository.
Configuration
Create build.config.mjs next to the root package.json to customize tool options:
export function parcel() {
return {
defaultTargetOptions: {
engines: { browsers: "> 1%, last 4 versions, not dead" },
},
};
}
export const assetsLookupGlob =
"src/{OrchardCore.Modules,OrchardCore.Themes}/*/Assets.json";
Use viteConfig for shared Vite configuration. Keep JavaScript modules consistent: add "type": "module" to a package when it must run as ESM, use the ESM Vue alias when required, and emit Vite scripts with type="module" in HTML.
Moving from Gulp
- Record each Gulp task's input files, output folder, minification, Sass processing, concatenation order, and watch behavior.
- Create a named
Assets.jsonaction. Map simple tasks tocopy,min,sass, orconcat; use Parcel, Vite, or Webpack for module bundling; userunfor a command that has its own build tool. - Put runtime libraries in the module or theme
Assets/package.json, and put shared build tools in.scripts/assets-manager/package.json. - Build both pipelines during the transition and compare generated files, source maps, and resource manifest URLs. Keep Gulp until the new output is verified.
- Switch development and CI commands to
yarn build,yarn watch, oryarn host. Remove the old Gulp task only after all consumers use the new output.
Do not treat Asset Manager migration as a replacement for Resource Management. The migration changes how files are generated; it does not change how Orchard Core serves or declares them.
Troubleshooting
- Node version warning: Use the version in
.node-version. The tool can offer to install it throughfnmor Volta. On Windows, restart the terminal after installing a version manager so its shims are onPATH. - Yarn or Corepack is missing: Run
npm install -g corepack, thencorepack enableandyarnfrom the repository root. Confirm the Yarn version matchespackage.json. - No action is found: Run from the repository root, confirm
Assets.jsonis at the module or theme root, and check the configuredassetsLookupGlobinbuild.config.mjs. - Copy output is missing during watch: This is expected.
watchdoes not run copy actions; useyarn build. - Parcel does not rebuild after deleting output: Run
yarn cleanto remove.parcel-cache, then build again. Give each Parcel action its owndest. - Concat uses the wrong package version: Align workspace versions, add a root
resolutionsentry, use an NPM alias, or replace concat with a bundler. Concat reads the hoisted root package. - Vite output is in the wrong folder: Set
build.outDirwithpath.resolve()and ensure theAssets.jsonsourcefolder contains the Vite config. - Vite files are unexpectedly minified or lack maps: Do not configure
build.minify; the Asset Manager's minification plugin owns this step. Use the non-min file for debugging and.min.*for production. - A library fails to transpile with Parcel: Check the package's module format and its
package.jsontypevalue. Use Vite or Webpack when the library needs explicit bundler configuration.
Sources
- Orchard Core Assets Manager guide — prerequisites,
Assets.json, Concurrently, supported actions, commands, package layout, bundlers, and troubleshooting notes. - Orchard Core 3.0.0 release notes — Asset Manager introduction, gradual Gulp replacement, backward compatibility, and the reason for the transition.
Signals
- GitHub stars
- 8k
- Forks
- 3k
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
orchardcore-asset-manager- Source
- github.com/orchardcms/orchardcore