Workspace builds
flog build runs ordinary build script lifecycles across a source-workspace
graph. It schedules each selected workspace at most once in deterministic
dependency-first order and then builds the selected app itself. A package with
no build script is reported as skipped, but traversal continues through it so
its transitive workspace dependencies still build. Actual script failures,
cycles, missing dependencies, and interruption remain errors.
Install the matching lock first. From a monorepo root, the development workflow
selects every workspace and finally the root's own build script when present:
flog install
flog build
From inside a workspace package, plain flog build selects that package and
its complete workspace dependency closure, including development-only
workspace edges. --workspace <selector> makes the selection explicit from any
directory and accepts a package name, workspace directory, owned file, or path
glob. Relative paths resolve from --cwd (or the process directory). Repeated
selectors must all be exact or all be globs, and aliases or overlapping globs
that select one workspace twice are rejected. --cwd only changes where Flog
locates the project and default package—it is not another selector.
Production source builds#
A deployment builder can select one app's production source graph with the same policy for installation and build:
flog install --workspace apps/website --prod
flog build --workspace apps/website --prod
--prod follows workspace dependencies from dependencies, eligible
optionalDependencies, and required peer providers while excluding branches
reachable only through devDependencies. Selection comes from the current
target graph in the validated flog.lock; neither command requests registry
metadata or changes lock bytes during a locked build.
This does not create a runtime-only node_modules tree. Every selected
workspace is compiled from source and retains its registry development tools,
and shared root registry development tooling remains installed. Runtime pruning
or copying bundled output into a final image is a separate phase.
If a selected source build genuinely imports a workspace reachable only through
a development edge, --prod omits that workspace and the script fails with its
normal package and lifecycle context. Declare a production/optional workspace
edge when the source build truly requires it, or use the full development
closure; Flog does not silently restore every editor/test adapter.
Build scripts and reporting#
Each selected package's normal prebuild, build, and postbuild lifecycle
runs when build exists. Missing build scripts are allowed and reported, so no
--if-present flag is needed. General flog run remains strict unless its own
--if-present option is supplied.
flog build is one graph-aware operation, not a recursive shell script. Remove
package prebuild hooks whose only purpose was a nested dependency query such
as flog run --workspace ... --dependencies-only --if-present build; otherwise
that hook requests overlapping work while the selected app is already being
built. Ordinary lifecycle hooks that perform package-local work remain valid.
Default execution is sequential and fail-fast. Validation can retain all permitted outcomes or schedule independent workspaces in parallel:
flog build --no-bail
flog build --no-bail --jobs auto
flog build --workspace apps/website --prod --json > build-results.json
Human and JSON output deterministically list selected workspaces, omitted
development-only workspaces, build-less skips, failures, blocked dependents,
interruptions, and nested-work reuse evidence. --jobs requires --no-bail;
--json implies it. Scripts that invoke Flog join the existing authenticated
command coordinator, preserving cancellation and at-most-once compatible work.
Coordination identity includes each package's effective selected dependency
subgraph: overlapping production and full builds may reuse equivalent leaf work,
but the app rebuilds when the full graph adds development-only inputs.