On This Page

Home / Apps/Builder Guide: Designing and Building Apps

Builder Guide: Designing and Building Apps

Preview Feature

This Preview feature is still being developed. We do not recommend using it in a production environment, because the feature might not be fully tested or optimized for performance, and related documentation could be incomplete.

Please continue to submit feedback through normal Cribl support channels, but assistance might be limited while the feature remains in Preview.

Use this guide to design, build, and ship Apps on the App Platform (Preview). It covers how Apps run, how they store state, how they call APIs, and how you package and deploy them. It assumes you’ve completed the Quickstart and are ready to go deeper.

See the Cribl Apps GitHub repository for public example Apps.

App Structure

Before you start building, decide how much your App needs to do. Start small. A single-screen App that solves one problem well is more useful than a sprawling App that tries to do everything. You can always add views later.

Single-screen Apps: Use these for a focused dashboard, a simple form-driven workflow (for example, look up a value, trigger an action), or a single API interaction behind a purpose-built UI.

Multi-step Apps: Use these when you need to guide users through a sequential workflow, combine data from multiple Cribl APIs or external services, or maintain complex state across multiple views.

Runtime Model and Sandbox

Apps run as embedded web applications inside an isolated iframe in the Cribl UI. Treat your App as an API client running in a constrained browser environment. For a security-review-oriented summary of execution boundaries, credentials, and outbound traffic, see Runtime, architecture, and security.

  • The Cribl shell owns global navigation and chrome.
  • Your App runs in the iframe as a standalone Single Page Application (SPA).
  • All reads and writes go through the documented Cribl APIs.
  • Persistent App state lives in the App Platform (Preview) KV store.

Iframe Sandbox Constraints

Because your App runs in an isolated iframe, certain standard browser capabilities are restricted to ensure security and Cribl UI stability.

CapabilityAvailable?Platform Alternative
fetch() to Cribl APIsHandled seamlessly by the Cribl fetch proxy.
localStorage / sessionStorageNot available in the sandbox. Use the KV store API.
IndexedDBNot available in the sandbox. Use the KV store API.
CookiesNot needed, auth is proxied automatically.
File downloads<a download>, Blob URLs.
Popups / new tabswindow.open(), <a target="_blank">.
Canvas with same-origin imagesFetch images through the proxy.

The AI-First Developer Workflow

The fastest way to build on the App Platform (Preview) is using AI coding assistants (like Cursor, GitHub Copilot, or Claude). The App Platform (Preview) provides explicit guardrails to help your AI write App Platform-compliant code, preventing it from hallucinating APIs or breaking sandbox constraints.

Expectations for Agent-Assisted Development

Agent-assisted (or “vibe-coded”) development is not the same as writing every line yourself. Assistants optimize for common web patterns and can still propose changes that break App Platform rules, even when AGENTS.md is in the project. Plan to iterate: a first green build or successful preview is a checkpoint, not necessarily done.

Typical missteps to watch for include:

  • Using localStorage, sessionStorage, IndexedDB, or cookies instead of the KV store.
  • Calling Cribl URLs or HTTP methods that are not in the bundled OpenAPI specification, or inventing request shapes the proxy cannot satisfy.
  • Omitting an external hostname from proxies.yml, or adding headers in App code that Cribl strips (use headers.inject for secrets instead).
  • Refactoring UI or fetch code in a way that drops iframe-safe patterns that already worked in an older revision.

When output is wrong, tighten your guidance. Paste console or network errors. Say what you clicked or loaded. Quote the relevant bullets from AGENTS.md or this guide so the tool realigns to documented behavior.

For prompting habits that reduce thrash, see Further Reading on Prompting and AI-Assisted Delivery.

1. Create and Scaffold

Create App and Live Preview require a Workspace Administrator. See Roles, permissions, and governance in the Admin Guide.

First, define the App in the Cribl UI to generate your scaffold script. The metadata step stores values in the App manifest and shows them in the Apps inventory (for example, ID, Display name, Version, and Author).

  • App ID - Stable folder name and deep-link segment (/apps/a/<app-id>/...). Prefer a short slug (letters, digits, hyphens). Keep it fixed once others bookmark links or automation depends on the path.
  • Display Name - Human-readable title in the Apps list. Plain language is fine. It does not need to match the App ID.
  • Description - What the App does so admins and users can judge fit when browsing installed Apps.
  • Author - Person, team, or company that builds or maintains the App.
  • Version - Initial semantic version in package.json. npm run package bumps it when you ship (see Package, version, and deploy).
  • Minimum Cribl version - Earliest Cribl release you wrote and tested against so admins can judge compatibility.
  1. In the Cribl UI, go to Apps > Create App from the top bar.
  2. On the Create your App screen, describe what you want to build, then select Next.
  3. Enter App ID, Display Name, Description, Author, Version, and Minimum Cribl version, then select Next.
  4. On the scaffold step, open a terminal in your IDE and set the working directory to match your IDE project folder. Select Using Cursor, Using Claude, or Generic, then select Copy Script. Paste the curl command into the terminal and run it.
  5. Leave the Create App wizard open in the browser through Live Preview. For the full sequence, see the Quickstart.

2. Initialize Your AI Assistant

The scaffolded project includes a critical file: AGENTS.md.

Before you start iterative AI-assisted coding, ensure your AI assistant reads this file. It covers authentication, documented APIs, and the KV store. It also covers iframe and sandbox rules plus other platform constraints. AGENTS.md documents the UI stack your scaffold ships with. Ground your AI with AGENTS.md so it uses the KV store instead of localStorage, writes every API key and secret to KV with encrypted=true, and follows the rest of that guidance.

3. Develop With Live Preview

Iterate on your code locally while previewing it live inside the Cribl UI context. For Live Preview, use Chrome, Edge, or Firefox. See Browser Support.

The preview iframe loads your dev server from your machine (typically loopback). Browsers can block that path from an HTTPS Cribl tab until the user allows local network or local device access for the Cribl origin. If Live Preview is blank, confirm those permissions in the browser (and on macOS, under System Settings > Privacy & Security > Local Network for the browser). See Browser Permissions for Live Preview in the Quickstart.

  1. Start your local dev server by running npm run dev in your project directory.
  2. In the Cribl UI, on the Create App wizard step that shows the scaffold instructions, select Live Preview. The preview pane opens in that flow.
  3. The App loads in an iframe inside Cribl and hot-reloads instantly as you or your AI assistant make code changes.

Live Preview binds your local dev server to the Cribl UI session where you opened it. After you switch Workspaces, Organizations, or move between a local deployment and Cribl.Cloud, stop the server (Ctrl+C in the terminal). Run npm run dev again before the next Live Preview. If you skip that restart, the App can fail to initialize in the iframe.

4. Package, Version, and Deploy

When you are ready to distribute your App, do not manually tar or zip directories. Use the provided build tooling. The version line you set at create time seeds package.json and the packaged manifest. For metadata you enter at create time, see Create and Scaffold.

  1. Run npm run package in your terminal.
  2. This compiles your App, auto-increments the patch version in package.json, and produces a valid .tgz archive. (You can override the version bump using npm run package -- --minor, npm run package -- --major, or npm run package -- --version x.y.z for an explicit semantic version.)
  3. Share this .tgz file. A Cribl administrator can install it by navigating to Apps > Installed Apps > Add App > Import from File. For the full install flow, see Install an App in the Admin Guide. For promoting builds across dev, staging, and production Workspaces and using Git for releases, see Development and release workflow for customer Apps in the Admin Guide.

Alternatively, from Live Preview in the Create App wizard you can select Deploy to package and upload in one step. See Step 6: Deploy in the Quickstart. Deploy installs into the Workspace where you started Create App. Use import into other Workspaces when you follow a multi-environment workflow.

State and Storage

The iframe runs in a sandboxed context without allow-same-origin. Do not use localStorage, sessionStorage, IndexedDB, or cookies. Doing so can cause your App to fail at runtime. The App Platform (Preview) provides a KV store as your only persistent store.

The KV Store

Each App has its own key-value store for persisting state, configuration, and secrets. The App Platform (Preview) isolates KV data per App, so each request from your App code applies only to that App’s keys.

REST shape: From App code, call fetch() with relative URLs /api/v1/kvstore/<key>. Replace <key> with any string your App owns (for example settings or user-preferences). PUT sends the raw body as the value. GET returns the stored string. Values are opaque to Cribl, so you typically stringify structured data before you write it and parse it after you read.

Values: A value can be any string you can send in the request body, not only small structured settings. Cribl treats the payload as opaque bytes for storage. In practice, Apps persist everything from short flags to large serialized documents, including multi-megabyte artifacts. If you store large values, load them asynchronously and keep the UI responsive. See Async hydration patterns.

Quota: Each App can store up to 1,000 keys by default. To raise the limit, contact Cribl Support.

API keys and credentials: Always write API keys, bearer tokens, passwords, and any other secret material to KV with encrypted=true. Plain (unencrypted) KV values are visible to anyone in your Organization who can use the KV APIs for that App context, not only to users who open your App UI. Encryption is required for secrets and is the supported way to reference them from proxies.yml with ${kv...} expressions resolved on the server.

Secrets: On PUT, append encrypted=true for every credential. Encrypted entries are write-only from the client. Reads return a redacted placeholder. Do not store secrets without encryption.

Key-Value Stores UI: Administrators can pre-seed or edit keys under App Settings > Key-Value Stores. The External API Access tab in App Settings shows how outbound calls are governed for the App. Organization-wide policy is described in External API access in the Admin Guide. Keys you create in Key-Value Stores share the same namespace as /api/v1/kvstore/... calls from App code. In the UI, add API keys and tokens only as encrypted entries.

Example: Write and Read settings From App Code

This snippet is ordinary App JavaScript (for example inside a React effect or handler). It writes a stringified configuration object under the key settings, then reads that key back.

// Write a setting (values are opaque strings; use JSON for structured data)
const settingsPayload = JSON.stringify({ theme: 'dark', refreshInterval: 30 });
await fetch('/api/v1/kvstore/settings', {
  method: 'PUT',
  headers: { 'Content-Type': 'text/plain;charset=UTF-8' },
  body: settingsPayload,
});

// Read it back
const resp = await fetch('/api/v1/kvstore/settings');
const raw = await resp.text();
const settings = JSON.parse(raw);

Async Hydration Patterns

Because KV access is async, plan for “no data yet” on initial render:

  • Loading gate: Wrap your root component in a loader that fetches required KV keys before rendering the main App.
  • Write-after-hydrate: Track a hasHydrated flag to prevent default local state from overwriting stored KV values during the initial load.

API Calls and Data Flow

Platform APIs

To call Cribl REST APIs, use standard fetch() with relative URLs. Cribl intercepts the request, injects the user’s auth headers, and routes it. Only call documented endpoints from the OpenAPI specification and API Reference.

External APIs and proxies.yml

To call external services, use standard fetch() with the full URL. Cribl intercepts the request and routes it through a server-side proxy.

You must declare all external domains in a proxies.yml file at your project root. Cribl enforces this declaration at runtime, ensuring administrators know exactly what external endpoints your App communicates with.

api.openai.com:
  paths:
    allowlist:
      - /v1/responses
  headers:
    inject:
      Authorization: '`Bearer ${kv.api_key}`'
  timeout: 30000

Sensitive headers set by App code are always stripped from outgoing requests for security. Use headers.inject in your proxies.yml to securely add credentials stored in the KV store.

Routing runs entirely inside your iframe using a client-side router (React Router, Vue Router, and so on) that integrates with window.history.

To allow users to bookmark specific views or share them with teammates, support deep linking by encoding minimal state into the URL.

In Safari, client-side routing in the iframe behaves differently than in Chrome, Edge, or Firefox. See Browser Support.

When a user opens a deep link, the host route uses this pattern:

/apps/a/<app-id>/<path-in-app>

For example: /apps/a/my-app/settings/general?tab=advanced.

Cribl restores the path segment below /apps/a/<app-id>/, plus the query string and hash, inside the iframe on load. Your App’s router reads that URL and renders the correct view.

Permissions and Access

Who can create Apps, install packages, and launch installed Apps is described in Roles, permissions, and governance in the Admin Guide.

Design your App to degrade gracefully based on permission variance:

  • Handle 403 responses explicitly: Catch 403 status codes and display a helpful message explaining the user lacks required access. Do not let a single failing API call render an empty screen for the entire App.
  • Dim or disable unavailable actions: If you can determine permissions via a preflight call, disable buttons rather than letting users hit a wall.
  • Document required roles: List the permissions your App requires in your App’s README or first-run screen.

Logging and Troubleshooting

  • Logging: Log significant events (API failures, destructive actions) with context, but do not log secrets or raw credentials.
  • DevTools: Use your browser’s DevTools to inspect network requests and console output. Attach DevTools to the iframe context, not the top-level Cribl shell.
  • Debug with your AI assistant: Copy failing console messages, stack traces, or redacted network error bodies from the iframe context. Paste them into your coding assistant with a short description of what you were doing. Because the assistant already has your repository, it can often propose a fix quickly. It does not run inside Cribl, so it may guess about App Platform behavior. When a suggestion looks off, ask it to reconcile the change with AGENTS.md, the OpenAPI specification and API Reference, and the Runtime Model and Sandbox and External APIs and proxies.yml.
  • Stale preview: If you change your build tooling configuration, perform a full browser reload of the Cribl tab to re-establish the Live Preview connection.
  • Preview after switching context: If you move between Workspaces, Organizations, or local and cloud deployments while using Live Preview, restart the local development server (npm run dev) so the App can initialize cleanly in the new context.
  • Server logs: Cribl records structured access for proxied traffic. Work with your Cribl administrator to correlate server-side logs with your App if you need request-level forensics.
  • npm errors or warnings: Switch your shell to Node.js 22.22.2 (for example with nvm install 22.22.2 and nvm use 22.22.2, or your version manager’s equivalent). Open a new terminal and retry the npm command.
  • cursor not in PATH: If scaffolding fails with Error: 'cursor' not found in PATH. Install Cursor from https://cursor.com, Cursor is installed but the CLI is not on your PATH. Enable or reinstall the shell command from Cursor, or add Cursor’s install directory to PATH per Cursor documentation. Retry in a new shell.

UX Guidelines

  • Bring your own UI: Build layouts, components, and styling in your App. Follow iframe rules in AGENTS.md and the Runtime Model and Sandbox.
  • Make primary actions obvious: Treat destructive actions explicitly with confirmation dialogs and clear danger styling.
  • Write clear error messages: Tell the user exactly what failed, whether they can fix it themselves, and when they need to talk to an administrator.

Further Reading on Prompting and AI-Assisted Delivery

These resources are not specific to Cribl, but they match how teams iterate with coding assistants: