# Build for the Developer Program

> Status: Beta

> Set up your environment, create a local project, deploy it into a sandbox, publish a package, and create a draft App Shop listing using the Rippling CLI.

> **Rippling:**
> Access to the **Developer Program** is gated behind a closed beta.

## Build process

Build, deploy, test, and install a managed package using the Developer Platform.

1.  Set up your local development environment, install the Rippling CLI, and sign in.
2.  Create an editor sandbox and switch your CLI context to it before you deploy.
3.  Create a local project with `rippling project init`.
4.  Add components with `rippling project add`, or write them directly in `rippling.manifest.ts`.
5.  Deploy the project to the editor sandbox with `rippling project deploy`. Edit the manifest and deploy again to preview each change.
6.  When the build is complete, create and publish the package from your Developer account with `rippling project package`.
7.  Create an installer sandbox and link it to the package.
8.  Install the published version in that sandbox and test.
9.  Create a draft App Shop listing for the published package.
10.  Submit the App Shop listing for review and publish after approval.

* * *

## CLI syntax & concepts

The Rippling CLI lets you build the package locally and reuse the same commands to deploy it, publish a version, and install it for testing. Each command runs against a context: your Developer account, an editor sandbox, or an installer sandbox.

See [Get started with the Rippling CLI](https://developer.rippling.com/documentation/rippling-platform/rippling-cli/get-started) for installation, shared flags, and the command list.

CLI commands follow this standard syntax:

```bash
rippling [--context <name>] <command> <subcommand> [--flag value]
```

-   **Developer account**: Use this primary context to create sandboxes, publish packages, and create an App Shop listing.
-   **Editor sandbox**: The account where you deploy and preview the project while you build.
-   **Installer sandbox**: A separate account where you install and test a published package version.
-   **Local project**: `rippling project init` creates your files locally without calling the API. Once you’ve edited `rippling.manifest.ts` and your components, run `rippling project deploy <context>` to apply the manifest to that sandbox.
-   **Input handling**: Pass `--input <file>` to provide a full JSON payload, or `--input -` to read directly from standard input (`stdin`). Do not combine `--input` with specific field flags.

* * *

## Set up your local development environment

Install the required CLI binaries, verify dependencies, and configure your credentials.

### Verify prerequisites

Ensure `Node.js`, `pnpm`, and `jq` are available locally:

```bash
node --version
pnpm --version
jq --version
```

If `jq` is missing (macOS), run:

```bash
brew install jq
```

If `pnpm` fails with `Cannot find matching keyid`, update Corepack and re-enable:

```bash
npm install -g corepack@latest
corepack enable
```

### Install the CLI

Install the Rippling CLI from the public npm registry and verify the installation:

```bash
npm install -g @rippling/cli@beta
rippling version
```

Keep the CLI updated with `rippling update`. To preserve installed agent skills while upgrading the CLI binary, run:

```bash
rippling update --skip-skills
```

### Authenticate the CLI

Authenticate your session and confirm your context configuration:

```bash
rippling login
rippling config context list --json
export EDITOR_SANDBOX_NAME="My app editor"
export INSTALLER_SANDBOX_NAME="My app installer"
export PACKAGE_NAME="My app"
export PACKAGE_KEY="my_app"
export INSTALL_KEY="demo"
export LISTING_NAME="My app"
```

`rippling login` launches a browser authentication workflow and stores session tokens securely in the system keychain. Ensure `developer-account` appears in the returned context list.

* * *

## Create an editor sandbox

Prepare the target sandbox for your deployed project. First, check for existing sandboxes:

```bash
rippling --context developer-account sandbox list --json
```

Each company has a sandbox quota of three sandboxes. When that quota is at capacity, sandbox create returns `HTTP 403` with `You've already created the maximum number of sandboxes`.

To reuse an existing sandbox, copy `handle` from the sandbox you want and skip the next step.

```bash
export EDITOR_HANDLE="<handle>"
```

### Provision the sandbox

Sandbox names must be unique within your organization. The `company_size` property accepts `SMALL` or `MEDIUM`.

```bash
cat > editor-sandbox-config.json <<'EOF'
{
  "developer": {
    "company_size": "MEDIUM"
  }
}
EOF

rippling --context developer-account sandbox create \
  --name "$EDITOR_SANDBOX_NAME" \
  --type developer \
  --description "Editor sandbox" \
  --config-override-file editor-sandbox-config.json \
  --json
```

Copy `handle` from that response, then run:

```bash
export EDITOR_HANDLE="<handle>"
```

To verify status if the sandbox is not ready immediately:

```bash
rippling --context developer-account sandbox get --id "<sandbox-id>" --json
```

Delete a sandbox you no longer need with:

```bash
rippling --context developer-account sandbox delete --id "SANDBOX_ID"
```

### Use the editor sandbox

Store the sandbox as the named context. `sandbox use` also makes that context the default, so later deploy commands push to this account.

```bash
rippling --context developer-account sandbox use \
  --alias "$EDITOR_HANDLE" \
  --context-name sandbox-editor
```

* * *

## Manage your project & package

Create the project locally. Note that this does not deploy or publish the project.

```bash
# Optional: create and enter a workspace directory if you don't have one
mkdir -p ~/projects && cd ~/projects

rippling project init --name "my-app"
cd my-app
```

> **Note for pnpm 10+:**
> If prompted regarding lifecycle build scripts, approve and rebuild `esbuild`:
>
> ```bash
> pnpm approve-builds esbuild
> pnpm rebuild esbuild
> ```

If migrating an older repository with lockfile references pointing to `npm.pkg.github.com`, configure a local `.npmrc` file with `@rippling:registry=https://registry.npmjs.org/` and execute `pnpm install` without the `--frozen-lockfile` flag.

You can also scaffold the first components during init by repeating `--with`:

```bash
rippling project init --name "my-app" \
  --with custom-app:my-app \
  --with function:page \
  --with function:grid
```

Allowed `--with` values include:

-   `custom-app:<name>`
-   `function:<name>`
-   `custom-object:<name>`
-   `agent:<name>`
-   `workflow:<name>`

### Add components

Add more components to your project with `project add`, or write them directly in the component files in `rippling.manifest.ts`. `project add` is local-only and updates the manifest and source files while preserving what is already included.

```bash
rippling project add custom-app --name my-app
rippling project add function --name page
rippling project add function --name grid
```

Component kinds include `custom-app`, `function`, `custom-object`, `agent`, and `workflow`.

```bash
rippling project add custom-object --name employee
rippling project add agent --name directory-helper
```

> **Rippling:**
> Keep the marker comments inside `rippling.manifest.ts` intact so future `project add` commands know where to inject new entries. Once added, you can build out your logic directly within the local files.

### Deploy & preview

Once you’ve completed adding components, deploy the current `rippling.manifest.ts` from into the editor sandbox. After the deployment finishes, a custom app will populate in the sandbox's UI.

First, `cd` into the directory in which the project was created:

```bash
cd my-app
```

Validate the project first, then deploy:

```bash
rippling --context sandbox-editor project validate
rippling --context sandbox-editor project deploy
```

> **Wait for deployment to complete:**
> `--timeout` sets how long the command waits (the default is 5 minutes). Pass `--yes` to skip the confirmation prompt:
>
> ```bash
> rippling --context sandbox-editor project deploy --yes --timeout 5m
> ```

If needed, make changes to `rippling.manifest.ts` and the component files, then run `project deploy` again to verify the changes in the sandbox UI. CLI authentication does **not** sign you into the browser. After the deployment finishes, a custom app will populate in the sandbox's UI.

### Publish the package

Once everything has been deployed and verified via the UI, create and publish an installable package from `rippling.manifest.ts`. Run these commands from the project root, with the `developer-account` context.

```bash
rippling --context developer-account project package \
  --name "$PACKAGE_NAME" \
  --type managed \
  --key "$PACKAGE_KEY" \
  --description "Employee directory." \
  --json
```

Copy the version `id`, then run:

```bash
export VERSION_ID="<id>"
```

```bash
rippling --context developer-account package get \
  --package-key "$PACKAGE_KEY" \
  --json
```

Copy `id`, then run:

```bash
export PACKAGE_ID="<id>"
```

**Notes:**

-   `--name` and `--type` are required when initially publishing the package. `--type` can be `managed` or `unmanaged`.
-   `--key` is optional. If omitted, the key is derived from `--name`. Set `--key` when a later install and listing commands need a stable key such as `my_app`.
-   Edit the name and description in `package.manifest.ts` if the saved package copy needs to differ.
-   For later releases, run `project package` again from the same project.

* * *

## Create the installer sandbox

Install the published package in a second sandbox. First, list your existing sandboxes:

```bash
rippling --context developer-account sandbox list --json
```

To reuse an existing non-editor sandbox, assign its handle directly (for example: `export INSTALLER_HANDLE="<handle>"`). Otherwise, provision a new installer sandbox:

```bash
cat > installer-sandbox-config.json <<'EOF'
{
  "developer": {
    "company_size": "SMALL"
  }
}
EOF

rippling --context developer-account sandbox create \
  --name "$INSTALLER_SANDBOX_NAME" \
  --type developer \
  --description "Installer sandbox" \
  --config-override-file installer-sandbox-config.json \
  --json
```

Copy `handle`, then run:

```bash
export INSTALLER_HANDLE="<handle>"
```

Store a sandbox as a named context and set that context as the default. Keep each command on separate lines:

```bash
rippling --context developer-account sandbox use \
  --alias "$INSTALLER_HANDLE" \
  --context-name sandbox-installer
```

```bash
rippling config context get --context sandbox-installer --json
```

Copy `companyID`, then run:

```bash
export INSTALLER_COMPANY_ID="<companyID>"
```

Link the sandbox to the package in `INSTALL` mode:

```bash
rippling --context developer-account package sandbox link --package-key "$PACKAGE_KEY" --sandbox-company-id "$INSTALLER_COMPANY_ID" --mode INSTALL --json
```

A successful payload confirms the targeted `package_key`, `sandbox_company_id`, `"mode": "INSTALL"`, and `"status": "COMPLETE"`.

* * *

## Install & verify the package

Install the published package into your installer sandbox:

```bash
rippling --context sandbox-installer package install \
  --managed \
  --package-key "$PACKAGE_KEY" \
  --install-key "$INSTALL_KEY" \
  --version-id "$VERSION_ID" \
  --json
```

Copy `id`, then run:

```bash
export MANAGED_INSTALL_ID="<id>"
```

```bash
rippling --context sandbox-installer package installation status \
  --install-id "$MANAGED_INSTALL_ID" \
  --json
```

Poll package installation status until the state resolves to `ACTIVE` or `ACTIVE_WITH_WARNINGS`. If the installation response provides a tracking identifier instead of an installation ID, pass `--tracker-id` instead.

To open and test the app in the Rippling UI:

1.  Sign into your installer sandbox via the Rippling web application (CLI authentication does not persist browser cookies).
2.  Navigate directly to `/custom-apps/<PACKAGE_KEY>__<INSTALL_KEY>__my_app` (for example: `/custom-apps/my_app__demo__my_app`).

* * *

## Create an App Shop listing

Create a draft listing from the Developer account:

```bash
rippling --context developer-account listing create \
  --name "$LISTING_NAME" \
  --package-id "$PACKAGE_ID" \
  --package-version-id "$VERSION_ID" \
  --package-version-name "0.1.0" \
  --json
```

Copy `id`, then run:

```bash
export LISTING_ID="<id>"
```

Submit the listing for Rippling review:

```bash
rippling --context developer-account listing submit --listing-id "$LISTING_ID"
```

Upon review and approval, the application will become available for customers to install from the Rippling App Shop.

* * *

## See also

-   [Get started with the Developer Program](https://developer.rippling.com/documentation/rippling-platform/developer-program/get-started)
-   [Get started with the Rippling CLI](https://developer.rippling.com/documentation/rippling-platform/rippling-cli/get-started)
-   [When to use Rippling primitives](https://developer.rippling.com/documentation/rippling-platform/custom-solutions/rippling-primitives)
-   [Overview of developer sandboxes](https://developer.rippling.com/documentation/rippling-platform/developer-program/sandboxes)

Source: https://developer.rippling.com/documentation/rippling-platform/developer-program/build

> For the complete documentation index, see [llms.txt](https://developer.rippling.com/llms.txt). Public pages have a Markdown version at the same URL with .md added.
