Loading image...Kiro

Product

  • About Kiro
  • IDE
  • CLI
  • Web
  • Mobile
  • Crew
  • Pricing
  • Downloads

For

  • Enterprise
  • Startups
  • Students

Community

  • Overview
  • Ambassadors
  • Discord
  • Events
  • Powers
  • Shop
  • Showcase

Resources

  • Docs
  • Blog
  • Changelog
  • FAQs
  • Report a bug
  • Suggest an idea
  • Billing support

Social

Site TermsLicenseResponsible AI PolicyLegalPrivacy PolicyCookie Preferences
Loading image...Kiro
  • Enterprise
  • Pricing
  • Docs
SIGN INDOWNLOADS
Loading image...Kiro

Get Started

InstallationAuthenticationYour first project

Models

OverviewAvailable modelsReasoning effort

Features

How Kiro works
Specs
Steering
Hooks
MCP
Permissions
Custom agents
Agent Skills
Powers
CompactionKiroignoreCheckpoints and rewind
Built-in tools
Configuration scopes

IDE 1.x

What's new in 1.0
Setup & First Run
Editor
Chat
Experimental
Troubleshooting0.x reference

CLI

What's new in 3.0
Setup & First Run
Terminal UI
Chat
Headless modeACPAuto complete
Experimental
2.x reference

Crew

Quick startInstallationRunning 24/7
Chat
Agent Capabilities
Features
Interfaces
Apps
Build your first app
Manifest reference
SDK / API reference
Publishing & guidelines
ConfigurationSecurityTroubleshooting

Web - Preview

Setup & First RunIdentity Center
Connect your repositories
Working with the agent
Autonomous modeAutomations
Sandbox

Mobile - Preview

Overview

Commands and Reference

CLI commandsSlash commandsBuilt-in toolsExit codesSettingsIDE keyboard shortcuts

Billing

OverviewManaging your subscriptionUpgrading your planDowngrading your planCancelling your planPurchasing add-on creditsManaging your paymentsManaging usage notificationsManaging your taxesContacting billing supportDeleting your accountRelated questions

Enterprise

ConceptsOnboarding quickstart
Connecting your identity provider
Subscribe your teamManage subscriptions
Governance
Monitor and track
SettingsManaged updatesBillingIAMSupported regions

Privacy and Security

OverviewData protectionCode referencesCompliance validationInfrastructure securityIAM permissionsFirewalls, proxies, and data perimetersVPC endpoints (AWS PrivateLink)

Guides

Overview
Language support
Learn by playing

Migration

Migrating from Q DeveloperMigrating from VSCodeUpgrading from Q CLI
  1. Docs
  2. Crew
  3. Apps
  4. Build your first app

Build your first app


Build, install, and run your first Crew app in about five minutes. We'll create an app with a manifest, one agent, one skill, and a simple dashboard UI page.

Prerequisites

  • Crew installed and running (kirocrew gateway)
  • Node.js 18+ (for apps with UI)

1. Create an app directory

my-dashboard/ ├── app.json ← manifest (required) ├── agents/ │ └── sample-agent.json ← agent definition ├── skills/ │ └── sample-skill/ │ └── SKILL.md ← skill knowledge file ├── ui/ ← frontend (if app has UI) │ ├── package.json │ ├── vite.config.ts │ ├── src/App.tsx │ └── .gitignore └── README.md

2. Write app.json

Every app needs an app.json at the repo root. This is the single source of truth for identity, resources, and store listing.

json
{ "name": "my-dashboard", "version": "0.1.0", "displayName": "My Dashboard", "description": "A Crew app: My Dashboard", "author": "yourname", "agents": ["agents/sample-agent.json"], "skills": ["skills/sample-skill"], "ui": { "entry": "dist/index.mjs", "pages": [ { "route": "/apps/my-dashboard", "label": "My Dashboard", "icon": "Package" } ] }, "permissions": { "api": ["/api/crons", "/api/status"], "events": ["notification"] } }

See Manifest reference for every field.

3. Write the UI page

ui/src/App.tsx is your app's React entry point. It's a standard React component using @kirocrew/app-sdk hooks and shared UI components.

tsx
import { useAppApi, useAppEvents } from '@kirocrew/app-sdk' import { Card, CardTitle, PageHeader, StatCard } from '@kirocrew/app-sdk/ui' import { useState, useEffect } from 'react' export default function MyDashboard() { const api = useAppApi() const [data, setData] = useState(null) useEffect(() => { api.get('/api/status').then(setData) }, []) useAppEvents('notification', (event) => { console.log('New notification:', event) }) return ( <> <PageHeader title="My Dashboard" subtitle="Custom app page" /> <div className="px-6 pb-8 overflow-y-auto flex-1 min-h-0"> <div className="grid gap-3.5 grid-cols-[repeat(auto-fit,minmax(150px,1fr))] mb-6"> <StatCard label="Status" value={data ? 'Online' : '...'} accent /> </div> <Card> <CardTitle>Content</CardTitle> <p className="text-sm text-muted">Your app content here.</p> </Card> </div> </> ) }
Tip

You do not npm install @kirocrew/app-sdk. The dashboard host provides it (and React, ReactDOM, lucide-react) at runtime through its import map. The bare @kirocrew/app-sdk specifier resolves to the host's vendored copy via window.__kirocrew_modules.

This guarantees your app shares the host's exact React instance (so hooks work) and stays a small bundle. Mark these as externals in your build (don't bundle them).

4. Write the agent

agents/sample-agent.json:

json
{ "name": "my-agent", "model": "auto", "description": "Analyzes data and generates reports", "prompt": "You are a data analyst assistant.", "tools": ["@kirocrew-core"] }

The @kirocrew-core tool reference tells Crew to include the core MCP server (spawn, learn, task, wait, register hook, send message).

5. Write the skill

skills/sample-skill/SKILL.md:

markdown
--- name: sample-skill description: A sample skill that teaches the agent about my domain. triggers: [sample, domain] always: false --- # Sample skill When the user asks about the sample domain: 1. Do the domain-specific first thing 2. Then check for the domain-specific second thing 3. Return the result in the standard format

The triggers list matches user message words. When any trigger appears in a message, the skill body is loaded for that turn.

6. Build the UI

bash
cd my-dashboard/ui npm install npm run build

This produces dist/index.mjs — the ESM bundle loaded by the dashboard.

Your vite.config.ts should mark React, ReactDOM, lucide-react, and @kirocrew/app-sdk as externals:

ts
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react' export default defineConfig({ plugins: [react()], build: { lib: { entry: 'src/App.tsx', formats: ['es'], fileName: 'index', }, rollupOptions: { external: ['react', 'react-dom', 'react/jsx-runtime', 'lucide-react', /^@kirocrew\/app-sdk/], }, }, })

7. Install and enable

bash
# Install via REST API curl -X POST http://localhost:5476/api/apps/install \ -H 'Content-Type: application/json' \ -d '{"source": "./my-dashboard"}' # Enable curl -X POST http://localhost:5476/api/apps/my-dashboard/enable

Or use the App Store UI in the dashboard → Install from local path.

Your app appears in the Crew dashboard sidebar.

8. Iterate

Turn on dev mode:

bash
kirocrew app dev my-dashboard

Now the workflow is:

  1. Edit ui/src/App.tsx
  2. cd ui && npm run build
  3. Dashboard hot-reloads automatically (dev mode watches ui/ and broadcasts an app_reload WebSocket event on any change)

Agent and skill changes take effect on the next agent invocation — no rebuild needed.

For faster iteration, symlink your source tree so file changes appear directly:

bash
ln -sfn /path/to/my-dashboard/ui ~/.kiro/crew/apps/my-dashboard/ui

Adding a backend

If your app needs its own HTTP server:

json
{ "backend": { "entryPoint": "backend/server.py", "port": "auto", "healthCheck": "/health", "routes": "/api/apps/my-dashboard", "type": "python" } }

The gateway launches your backend as a subprocess, reverse-proxies /apps/my-dashboard/api/* to it, and signs each proxied request with an HMAC header. Your backend verifies the signature using kirocrew-client:

python
from kirocrew_client import verify_proxy_request if not verify_proxy_request(request, 'my-dashboard'): return Response(status=401)

The signature is over timestamp:method:/api/path[?query]:sha256(body) with the app secret as the key. Timestamps must be within ±60s of now.

Adding a cron job

Declare it in the manifest:

json
{ "crons": [ { "name": "daily-check", "cron_expr": "0 9 * * 1-5", "message": "Run the daily check for my-dashboard", "agent": "my-agent" } ] }

Crew registers the cron on enable and deregisters on disable. Owned via created_by='app:my-dashboard' in the ledger.

Adding a lifecycle hook

For install-time build steps:

json
{ "setup": { "onInstall": "cd ui && npm install && npm run build", "onUpdate": "cd ui && npm install && npm run build" } }

Scripts run with set -euo pipefail, NONINTERACTIVE=1, and a minimal environment. They must exit 0 on success.

App SDK Hooks

Available in @kirocrew/app-sdk:

HookPurpose
useAppApi()Permission-scoped HTTP client (GET/POST/PUT/PATCH/DELETE)
useAppEvents(event, cb)Subscribe to real-time WebSocket events
useTheme()Reactive theme (mode, accent, colorTheme)
useAppInfo()App metadata (name, version, permissions)
useNavigate()Navigate to Crew routes
useNotify()Show toast notifications
useNavBadge()Update sidebar badge count
useChatLauncher()Navigate to chat with optional agent and message

Shared UI Components

Available in @kirocrew/app-sdk/ui:

Card, CardTitle, Btn, SendBtn, Input, SearchInput, Badge, AimBadge, StatCard, Skeleton, ContentSkeleton, EmptyState, PageHeader, Toggle, InfoTip, SegmentedControl, MarkdownRenderer.

Page updated: August 4, 2026
Apps
Manifest reference