Skip to content

Evaluate without adopting the SDK

You want to try Project Builder in a repository you already have — without adding @pbuilder/sdk to its package.json and without restoring that file after every run. builder init --no-sdk-dependency gives you that: the CLI skips the SDK declaration and its install, and builder execute runs against an SDK that is simply present in node_modules.

  • The builder CLI and Bun are installed — see Installation.

  • You know what is already modified, so you can tell trial changes apart later:

    Terminal window
    git status --short
  1. Preview what init will do. Nothing is written or installed:

    Terminal window
    builder init . --no-sdk-dependency --dry-run --non-interactive

    With --no-sdk-dependency alone, the plan contains no package.json step at all. The skill and marker lines are a plan, not an exact prediction of what happens to files that already exist.

  2. Initialise the workspace:

    Terminal window
    builder init . --no-sdk-dependency --non-interactive

    init adds no SDK entry, no generate:types script and runs no install. It also removes nothing: an SDK version or script already in package.json stays, and an SDK already installed stays usable. The warning it prints lists the ways to provide an SDK; the next step is one of them.

    Want the generate:types script anyway? Add --skip-types-script=false. The full flag matrix is in the builder init reference.

  3. Put an SDK in node_modules without declaring it. execute needs a complete SDK at node_modules/@pbuilder/sdk. With npm or Bun you can install one without touching package.json or the lockfile:

    Terminal window
    npm install --no-save @pbuilder/sdk
    # or
    bun add --no-save @pbuilder/sdk

    pnpm and Yarn have no equivalent option — their add commands always record the dependency. A later install or prune by your package manager can remove an unsaved package; if that happens, run the command again.

    Skip this step if the repository already has an SDK installed.

    Alternative: use a global SDK. Instead of installing into node_modules, point sdk.root in project-builder.json at a global install — for example the directory bun add -g @pbuilder/sdk creates:

    project-builder.json
    {
    "sdk": {
    "root": "/Users/me/.bun/install/global/node_modules/@pbuilder/sdk"
    }
    }

    The first committing builder execute then creates a single symbolic link, node_modules/@pbuilder/sdk, pointing at that root. To regenerate types by hand in this setup, see Type generation with sdk.root.

    To leave project-builder.json untouched as well, name the same directory per run with --sdk-root (before <collection>:<schematic>) or once with the BUILDER_SDK_ROOT environment variable instead. Both override sdk.root — see SDK source.

  4. Create and run a schematic:

    Terminal window
    builder new schematic hello
    builder execute default:hello

    new schematic writes schematics/hello/ and registers it in project-builder.json. The generated factory is an empty stub, so this first run reports no changes. From here on, follow Your first schematic to give it real logic.

With no declaration anywhere, execute requires SDK 0.2.4 or newer — the oldest version the CLI is tested against. To require a specific floor without adding a dependency, set it in project-builder.json:

{
"sdk": {
"version": "0.2.4"
}
}

A declaration in package.json still takes priority over sdk.version, and an invalid value fails instead of falling back. The full selection order is in the SDK requirement reference; each failure reason and its repair is in SDK diagnostics.

The CLI never edits Git’s exclude files — do it yourself if you want git status to stay quiet during the trial. Resolve the right file first; in a worktree, .git is not a directory:

Terminal window
git rev-parse --git-path info/exclude

Then add the entries that apply, and only for paths that are currently untracked:

/project-builder.json
/.claude/skills/pbuilder/
/schematics/

Local excludes affect untracked files only. They do not hide changes to tracked files — an agent-file marker, a manifest, a lockfile or generated code still show up in git diff, and you still need to review them. Do not use git update-index --skip-worktree or --assume-unchanged to hide those instead. Never exclude a schematics/ directory that already existed in the repository.

Work from what the trial actually changed — not from a blanket reset:

  1. Run git status --short and git diff, and compare with the status you noted before the trial.
  2. Remove only files the trial created: project-builder.json, schematics/ and .claude/skills/pbuilder/ — when they did not exist before.
  3. Undo only trial changes in tracked files, such as the marker block added to AGENTS.md or CLAUDE.md. Keep any edits of your own.
  4. Remove the trial SDK from node_modules if you installed one. If you used an external root, remove the link it left behind (test -L node_modules/@pbuilder/sdk && rm node_modules/@pbuilder/sdk) — after removing the sdk.root key, or unsetting BUILDER_SDK_ROOT; --sdk-root leaves nothing else to undo. Also remove the lines you added to the exclude file.

Do not reach for git clean or git reset --hard: they also destroy work that has nothing to do with the trial.

When the trial convinces you:

  1. Remove the exclude lines you added, and decide which of project-builder.json, schematics/ and .claude/skills/pbuilder/ to commit.

  2. Declare the SDK with one package-manager command, pinning a version if you need reproducible installs:

    Package manager Command
    npm npm install --save-dev @pbuilder/sdk
    pnpm pnpm add -D @pbuilder/sdk
    Yarn yarn add --dev @pbuilder/sdk
    Bun bun add -D @pbuilder/sdk

    This changes package.json and may change the lockfile.

  3. Optionally let init add the missing generate:types script. --force also merges project-builder.json and regenerates the skill files and marker, so preview first and review the full diff afterwards:

    Terminal window
    builder init . --force --dry-run --non-interactive
    builder init . --force --non-interactive