Node Profile
The Node profile is selected when:
--profile nodeis provided- config has
profile = "node" - no config is loaded and Shadowtree detects the nearest
package.jsonupward from the current directory
Node built-ins resolve the nearest package.json directory and generate shell
commands that cd there before invoking the package manager or tool. This
makes subdirectory invocation run against the package root.
Every Node built-in recipe has sandboxed = false by default because package
manager and framework commands commonly mutate lockfiles, dependency state,
caches, and generated outputs.
Package Manager Detection
Detection order:
packageManagerprefix:pnpm,yarn,bun, ornpm- lockfiles:
pnpm-lock.yaml,yarn.lock,bun.lockb,bun.lock,package-lock.json,npm-shrinkwrap.json - default
npm
Built-In Recipes
install npm|pnpm|yarn|bun install
dev package script dev, or inferred framework dev command
build package script build, or inferred framework build command
start package script start, or inferred framework start/preview command
test package script test, or Vitest/Jest/Playwright/Bun fallback
lint package script lint, or ESLint/Oxlint/Biome
fmt package script fmt/format, or Prettier/Oxfmt/Biome
typecheck package script typecheck/type-check, or detected type checkers
check available lint, typecheck, and test recipes in that order
Package scripts fill gaps without overriding predefined Node recipe names.
Command Forms
- Package scripts run
<pm> run <script> -- {@}. - Tool commands run
npm exec -- <bin> ... {@},pnpm exec <bin> ... {@},yarn exec <bin> ... {@}, orbunx <bin> ... {@}. - Bun projects without a test script use
bun test {@}when Vitest is not installed.
Framework Inference
For dev, build, and start:
next:next dev,next build,next startvite:vite,vite build,vite previewnuxt:nuxt dev,nuxt build,nuxt previewastro:astro dev,astro build,astro preview@sveltejs/kit:vite,vite build,vite preview
Test Inference
- Script
testwins. - Bun projects use installed
vitestfirst, otherwisebun test. - Other projects use installed
vitest, thenjest, thenplaywright testwhen@playwright/testis installed.
Lint Inference
- Script
lintwins. - ESLint markers:
eslintdependency,eslint.config.*,.eslintrc*, or packageeslintConfig; commandeslint .. - Oxlint markers:
oxlintdependency,oxlint.config.*,.oxlintrc.json, or.oxlintrc.jsonc; commandoxlint. - Biome markers:
@biomejs/biomedependency,biome.json, orbiome.jsonc; commandbiome lint ..
Format Inference
- Script
fmtwins, then scriptformat. - Prettier markers:
prettierdependency,prettier.config.*,.prettierrc*, or packageprettier; commandprettier --write .. - Oxfmt markers:
oxfmtdependency,oxfmt.config.*,.oxfmtrc.json, or.oxfmtrc.jsonc; commandoxfmt. - Biome markers:
@biomejs/biomedependency,biome.json, orbiome.jsonc; commandbiome format --write ..
Typecheck Inference
- Script
typecheckwins, then scripttype-check. - Otherwise Shadowtree runs every detected checker in stable order:
vue-tsc --noEmit,svelte-check, thentsc --noEmit. tsc --noEmitis included whentypescriptis installed ortsconfig.jsonexists.
Script Recipe Names
Before a package script becomes a recipe name, Shadowtree replaces : and
every character outside [A-Za-z0-9._-] with -, collapses repeated -, trims
leading and trailing -, and skips empty or reserved names.
If multiple scripts normalize to the same recipe name, the script whose
original name already equals the normalized name wins; otherwise the
lexicographically first original script name wins. For example, package script
lint:fix becomes recipe lint-fix, but the generated command still runs the
original script key lint:fix.