# How BuilderIO/agent-native Handles Dependencies Defined in Root Files

> Discover how BuilderIO/agent-native manages root dependencies using a pnpm monorepo architecture controlled by pnpm-workspace.yaml and custom guard scripts for efficient dependency management.

- Repository: [Builder.io/agent-native](https://github.com/BuilderIO/agent-native)
- Tags: internals
- Published: 2026-07-01

---

**BuilderIO/agent-native manages root-level dependencies through a pnpm monorepo architecture where the root [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) contains only development-time tooling, while runtime dependencies are centrally controlled via [`pnpm-workspace.yaml`](https://github.com/BuilderIO/agent-native/blob/main/pnpm-workspace.yaml) catalogs and enforced by custom guard scripts.**

Managing dependencies in a JavaScript monorepo requires strict coordination to prevent version conflicts and duplicated packages. BuilderIO/agent-native solves this through a centralized dependency strategy that leverages pnpm's workspace protocol alongside automated validation. This approach ensures that root file definitions serve as the single source of truth for the entire repository.

## Root package.json as a Development-Only Manifest

The root [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) in BuilderIO/agent-native serves exclusively as a manifest for **development-time tooling** rather than application runtime dependencies. It contains only `devDependencies` required to build, test, or lint any package within the workspace, including tools like `concurrently`, `oxlint`, `prettier`, and `tsx`.

This approach ensures that build tools and test runners are installed once at the repository root rather than duplicated across individual package `node_modules` directories. By keeping runtime dependencies out of the root manifest, the repository maintains a clear separation between development infrastructure and package-specific requirements.

## Centralized Version Control via pnpm-workspace.yaml

The repository defines its workspace structure and dependency versions in [`pnpm-workspace.yaml`](https://github.com/BuilderIO/agent-native/blob/main/pnpm-workspace.yaml). This configuration file declares the workspace layout (`packages/*` and `templates/*`), a **catalog** of approved dependency versions, and **overrides** that force every package to use identical versions of shared libraries like React and Tailwind.

The catalog acts as a central version lock-file. When a package lists a dependency that exists in the catalog without specifying an explicit version, it automatically inherits the catalog version. This eliminates the need to update version numbers across dozens of individual [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) files when upgrading shared libraries.

### Version Overrides for Consistency

The `overrides` section in [`pnpm-workspace.yaml`](https://github.com/BuilderIO/agent-native/blob/main/pnpm-workspace.yaml) ensures that critical libraries use identical versions across the entire monorepo. For example, the configuration forces `react` and `react-dom` to version `19.2.7` and `@types/react` to `^19.2.14` regardless of what individual packages might specify. This prevents the "dependency hell" scenario where different packages pull in conflicting versions of shared libraries.

## Enforcing the Workspace Protocol with Guard Scripts

Internal packages reference each other using the **`workspace:*`** protocol rather than specific version numbers. The [`scripts/guard-public-packages.ts`](https://github.com/BuilderIO/agent-native/blob/main/scripts/guard-public-packages.ts) script validates that all intra-repository dependencies use this protocol and that only packages on the npm-publish allow-list are exposed with proper semver ranges.

The `localWorkspaceDependencyFailures` function in this script checks that any dependency referencing another `@agent-native` package uses `workspace:*` in the source:

```typescript
function localWorkspaceDependencyFailures(
  pkgName: string,
  field: string,
  dependencies: Record<string, string> | undefined,
): string[] {
  if (!dependencies) return [];
  return Object.entries(dependencies)
    .filter(([dep, version]) =>
      // Must stay "workspace:*" when referring to another @agent-native package
      workspacePackageNames.has(dep) && version !== "workspace:*",
    )
    .map(
      ([dep, version]) =>
        `${pkgName} ${field}.${dep} must stay workspace:* in source, not ${version}; pnpm pack rewrites it for npm publishing`,
    );
}

```

This validation ensures that internal packages remain properly linked during development, while `pnpm pack` automatically rewrites these references to proper semver ranges during the publishing process.

### Pre-Publish Validation Checks

The same guard script enforces that **workspace-only packages** stay private and are excluded from changesets. It verifies that published packages have `publishConfig.access` set to `"public"` and `publishConfig.provenance` set to `true`. Additionally, it checks that no raw TypeScript files are referenced in `main`, `exports`, or `bin` fields—all entries must point to compiled JavaScript or [`.d.ts`](https://github.com/BuilderIO/agent-native/blob/main/.d.ts) files in the `dist/` directory.

## Automated Build Synchronization

After `pnpm install` completes, the `postinstall` script triggers [`scripts/prebuild-workspace-packages.ts`](https://github.com/BuilderIO/agent-native/blob/main/scripts/prebuild-workspace-packages.ts). This script detects missing build artifacts for each workspace package and clears stale TypeScript build-info files (`.tsbuildinfo`) to ensure fresh compilation.

The `firstMissingOutput` function checks whether expected output files exist in each package's directory:

```typescript
function firstMissingOutput(target: PackageTarget): string | null {
  for (const output of target.expectedOutputs) {
    if (!existsSync(path.join(target.dir, output))) return output;
  }
  return null;
}

```

If artifacts are missing, the script clears stale build information and runs `pnpm run build` selectively for only those packages requiring recompilation. This ensures that the compiled `dist/` output matches the exported entries declared in each package's [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) without forcing unnecessary rebuilds of unchanged code.

## Summary

- The root [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) contains only `devDependencies` for development tooling, avoiding duplication across the monorepo while keeping runtime dependencies package-specific.
- [`pnpm-workspace.yaml`](https://github.com/BuilderIO/agent-native/blob/main/pnpm-workspace.yaml) centralizes version management through catalogs and overrides, ensuring consistent library versions across all workspace packages.
- The `workspace:*` protocol enforces proper internal linking, validated by [`scripts/guard-public-packages.ts`](https://github.com/BuilderIO/agent-native/blob/main/scripts/guard-public-packages.ts) to prevent improper version references.
- Automated build synchronization via [`scripts/prebuild-workspace-packages.ts`](https://github.com/BuilderIO/agent-native/blob/main/scripts/prebuild-workspace-packages.ts) ensures compiled outputs match exported entries without unnecessary rebuilds.

## Frequently Asked Questions

### Why does BuilderIO/agent-native keep only devDependencies in the root package.json?

Keeping only `devDependencies` in the root [`package.json`](https://github.com/BuilderIO/agent-native/blob/main/package.json) ensures that build tools, linters, and test runners are installed once at the repository level rather than duplicated in each package's `node_modules`. This reduces disk space usage and installation time while maintaining a clear separation between development infrastructure and runtime dependencies required by individual applications.

### What happens if a package references internal dependencies without the workspace:* protocol?

The [`scripts/guard-public-packages.ts`](https://github.com/BuilderIO/agent-native/blob/main/scripts/guard-public-packages.ts) script will fail validation during pre-publish checks. The `localWorkspaceDependencyFailures` function specifically filters for internal dependencies that don't use the `workspace:*` protocol and generates error messages indicating that the version must remain `workspace:*` in source. This allows `pnpm pack` to properly rewrite these references to semver ranges during the npm publishing process.

### How does the pnpm-workspace.yaml catalog prevent version conflicts?

The catalog in [`pnpm-workspace.yaml`](https://github.com/BuilderIO/agent-native/blob/main/pnpm-workspace.yaml) acts as a centralized version registry that provides a single source of truth for dependency versions. When a package lists a dependency that exists in the catalog without specifying a version, it automatically inherits the catalog version. The `overrides` section further ensures that critical libraries like React use identical versions across every package, preventing runtime conflicts from incompatible library versions.

### When does the prebuild script trigger and what does it optimize?

The prebuild script triggers automatically after `pnpm install` via the `postinstall` hook. It optimizes the build process by using `firstMissingOutput` to check for missing compiled files and only rebuilding packages that actually require recompilation. The script also clears stale TypeScript build-info files to prevent compilation errors from outdated incremental build data, ensuring that `pnpm run build` runs fresh only for packages with missing or outdated artifacts.