App Manifest
The app manifest is the configuration file that defines your appβs metadata, permissions, assets, and components. This guide covers all manifest options and best practices.
Basic Structure
Every Karrio app must have a manifest.ts
file that exports an AppManifest
object:
manifest.ts1import { AppManifest } from "@karrio/app-store/types"; 2 3export const manifest: AppManifest = { 4 id: "my-app", 5 name: "My App", 6 version: "1.0.0", 7 description: "A description of what this app does", 8 author: { 9 name: "Your Name", 10 email: "you@example.com", 11 website: "https://yourwebsite.com", 12 }, 13 permissions: ["manage_shipments"], 14 assets: { 15 icon: "./assets/icon.svg", 16 screenshots: ["./assets/screenshot1.png"], 17 readme: "./README.md", 18 }, 19 components: { 20 main: "./component.tsx", 21 }, 22};
Manifest Properties
Required Fields
id
(string)
Unique identifier for your app. Must be lowercase, alphanumeric, and may contain hyphens.
1export const manifest: AppManifest = { 2 id: "shipping-optimizer", // β Good 3 // id: 'Shipping_Optimizer', // β Bad: uppercase and underscore 4 // id: 'shipping optimizer', // β Bad: contains space 5};
name
(string)
Human-readable name displayed in the UI.
1export const manifest: AppManifest = { 2 name: "Shipping Optimizer", // β Good 3 // name: '', // β Bad: empty string 4};
version
(string)
Semantic version number following semver format.
1export const manifest: AppManifest = { 2 version: "1.0.0", // β Good 3 version: "1.2.3-beta.1", // β Good: pre-release 4 // version: '1.0', // β Bad: incomplete version 5};
description
(string)
Brief description of your appβs functionality.
1export const manifest: AppManifest = { 2 description: 3 "Optimize shipping routes and reduce costs with AI-powered recommendations", 4};
author
(object)
Information about the app developer.
1export const manifest: AppManifest = { 2 author: { 3 name: "Acme Corp", 4 email: "support@acme.com", 5 website: "https://acme.com", // Optional 6 }, 7};
Assets Configuration
assets
(object)
Defines static assets used by your app.
1export const manifest: AppManifest = { 2 assets: { 3 icon: "./assets/icon.svg", // Required: app icon 4 screenshots: [ 5 // Optional: screenshots for app store 6 "./assets/screenshot1.png", 7 "./assets/screenshot2.png", 8 "./assets/demo.gif", 9 ], 10 readme: "./README.md", // Optional: detailed documentation 11 }, 12};
Asset Requirements:
- Icon: SVG format, 64x64px recommended
- Screenshots: PNG/JPG format, 1200x800px recommended
- README: Markdown format with app documentation
Components Configuration
components
(object)
Defines React components for different app views.
1export const manifest: AppManifest = { 2 components: { 3 main: "./component.tsx", // Required: main app component 4 configuration: "./configuration.tsx", // Optional: settings component 5 widget: "./widget.tsx", // Optional: dashboard widget 6 onboarding: "./onboarding.tsx", // Optional: setup wizard 7 }, 8};
Permissions System
permissions
(array)
Defines what Karrio APIs and data your app can access.
1export const manifest: AppManifest = { 2 permissions: [ 3 // App management permissions 4 "manage_apps", 5 6 // Carrier management permissions 7 "manage_carriers", 8 9 // Order management permissions 10 "manage_orders", 11 12 // Team management permissions 13 "manage_team", 14 15 // Organization owner permissions 16 "manage_org_owner", 17 18 // Webhook management permissions 19 "manage_webhooks", 20 21 // Data management permissions (includes tracking, analytics) 22 "manage_data", 23 24 // Shipment management permissions (includes addresses, parcels, rates) 25 "manage_shipments", 26 27 // System management permissions (includes users, system configuration) 28 "manage_system", 29 ], 30};
Permission Groups:
manage_apps
- Full access to app managementmanage_carriers
- Full access to carrier configurationsmanage_orders
- Full access to order managementmanage_team
- Full access to team member managementmanage_org_owner
- Organization owner permissionsmanage_webhooks
- Full access to webhook managementmanage_data
- Full access to data, analytics, and audit logsmanage_shipments
- Full access to shipments, addresses, parcels, trackingmanage_system
- Full administrative access to system settings and users
API Routes Configuration
api
(object)
Defines server-side API endpoints for your app.
1export const manifest: AppManifest = { 2 api: { 3 routes: { 4 // Basic CRUD operations 5 data: "./api/data/route.ts", 6 "data/[id]": "./api/data/[id]/route.ts", 7 8 // Webhook handlers 9 "webhooks/shopify": "./api/webhooks/shopify/route.ts", 10 "webhooks/stripe": "./api/webhooks/stripe/route.ts", 11 12 // External integrations 13 "integrations/oauth": "./api/integrations/oauth/route.ts", 14 "integrations/sync": "./api/integrations/sync/route.ts", 15 16 // Background jobs 17 "jobs/sync": "./api/jobs/sync/route.ts", 18 "jobs/cleanup": "./api/jobs/cleanup/route.ts", 19 }, 20 }, 21};
Settings Configuration
settings
(object)
Defines configuration options for your app.
1export const manifest: AppManifest = { 2 settings: { 3 required_metafields: [ 4 { 5 key: "api_key", 6 type: "password", 7 label: "API Key", 8 description: "Your external service API key", 9 is_required: true, 10 }, 11 { 12 key: "webhook_url", 13 type: "url", 14 label: "Webhook URL", 15 description: "URL for receiving webhooks", 16 is_required: false, 17 }, 18 { 19 key: "sync_interval", 20 type: "number", 21 label: "Sync Interval (minutes)", 22 description: "How often to sync data", 23 default: "30", 24 min: 5, 25 max: 1440, 26 }, 27 { 28 key: "enabled_features", 29 type: "multi_select", 30 label: "Enabled Features", 31 description: "Select which features to enable", 32 options: [ 33 { value: "auto_sync", label: "Automatic Sync" }, 34 { value: "notifications", label: "Email Notifications" }, 35 { value: "analytics", label: "Analytics Tracking" }, 36 ], 37 }, 38 ], 39 default_configuration: { 40 sync_interval: "30", 41 enabled_features: ["auto_sync"], 42 }, 43 }, 44};
Metafield Types:
string
- Text inputpassword
- Password input (encrypted)number
- Numeric inputboolean
- Checkboxurl
- URL validationemail
- Email validationselect
- Dropdown selectionmulti_select
- Multiple selectiontextarea
- Large text inputjson
- JSON object input
Categories and Tags
category
(string)
Primary category for app store organization.
1export const manifest: AppManifest = { 2 category: "shipping", // Primary category 3 tags: [ 4 // Additional tags for discovery 5 "optimization", 6 "automation", 7 "ai", 8 "cost-reduction", 9 ], 10};
Available Categories:
shipping
- Shipping and logisticsecommerce
- E-commerce integrationsanalytics
- Analytics and reportingautomation
- Workflow automationutilities
- Utility toolsintegrations
- Third-party integrations
Lifecycle Hooks
hooks
(object)
Define lifecycle event handlers.
1export const manifest: AppManifest = { 2 hooks: { 3 install: "./hooks/install.ts", // Run on app installation 4 uninstall: "./hooks/uninstall.ts", // Run on app uninstallation 5 upgrade: "./hooks/upgrade.ts", // Run on app updates 6 configure: "./hooks/configure.ts", // Run on configuration changes 7 }, 8};
Environment Configuration
environment
(object)
Define environment-specific settings.
1export const manifest: AppManifest = { 2 environment: { 3 development: { 4 api_base_url: "http://localhost:3000", 5 debug: true, 6 }, 7 staging: { 8 api_base_url: "https://staging-api.myapp.com", 9 debug: false, 10 }, 11 production: { 12 api_base_url: "https://api.myapp.com", 13 debug: false, 14 }, 15 }, 16};
Advanced Configuration
Conditional Features
Use conditional logic for complex app configurations:
1const manifest: AppManifest = { 2 id: "advanced-app", 3 name: "Advanced App", 4 version: "2.0.0", 5 6 // Conditional permissions based on app type 7 permissions: [ 8 "manage_shipments", 9 ...(process.env.NODE_ENV === "development" ? ["admin:debug"] : []), 10 ], 11 12 // Dynamic component loading 13 components: { 14 main: "./component.tsx", 15 ...(process.env.FEATURE_ANALYTICS === "enabled" && { 16 analytics: "./analytics.tsx", 17 }), 18 }, 19 20 // Environment-specific API routes 21 api: { 22 routes: { 23 data: "./api/data/route.ts", 24 ...(process.env.NODE_ENV !== "production" && { 25 debug: "./api/debug/route.ts", 26 }), 27 }, 28 }, 29};
Multi-tenant Configuration
Configure apps for multi-tenant scenarios:
1export const manifest: AppManifest = { 2 id: "multi-tenant-app", 3 name: "Multi-tenant App", 4 version: "1.0.0", 5 6 // Tenant-specific settings 7 settings: { 8 tenant_configuration: { 9 subdomain_required: true, 10 custom_branding: true, 11 isolated_data: true, 12 }, 13 required_metafields: [ 14 { 15 key: "tenant_id", 16 type: "string", 17 label: "Tenant ID", 18 description: "Unique identifier for this tenant", 19 is_required: true, 20 validation: { 21 pattern: "^[a-z0-9-]+$", 22 message: "Must be lowercase alphanumeric with hyphens", 23 }, 24 }, 25 ], 26 }, 27};
Validation and Schema
Add validation to your manifest:
1import { z } from "zod"; 2 3const manifestSchema = z.object({ 4 id: z.string().regex(/^[a-z0-9-]+$/, "Invalid app ID format"), 5 name: z.string().min(1).max(50), 6 version: z.string().regex(/^\d+\.\d+\.\d+/, "Invalid semver format"), 7 description: z.string().min(10).max(500), 8 permissions: z.array(z.string()), 9 components: z.object({ 10 main: z.string(), 11 configuration: z.string().optional(), 12 }), 13}); 14 15export const manifest: AppManifest = manifestSchema.parse({ 16 // Your manifest configuration 17});
Best Practices
1. Security Considerations
1export const manifest: AppManifest = { 2 // β Request only necessary permissions 3 permissions: ["manage_shipments"], // Minimal permissions 4 5 // β Validate sensitive configuration 6 settings: { 7 required_metafields: [ 8 { 9 key: "api_key", 10 type: "password", // Automatically encrypted 11 validation: { 12 pattern: "^sk_[a-zA-Z0-9]{24}$", 13 message: "Invalid API key format", 14 }, 15 }, 16 ], 17 }, 18};
2. Performance Optimization
1export const manifest: AppManifest = { 2 // β Lazy load optional components 3 components: { 4 main: "./component.tsx", 5 analytics: "./analytics.tsx", // Loaded only when needed 6 }, 7 8 // β Optimize asset loading 9 assets: { 10 icon: "./assets/icon.svg", // SVG for scalability 11 screenshots: ["./assets/screenshot1.webp"], // WebP for compression 12 }, 13};
3. Maintainability
β Use constants for reusable values1const APP_ID = "shipping-optimizer"; 2const API_VERSION = "v1"; 3 4export const manifest: AppManifest = { 5 id: APP_ID, 6 version: "1.0.0", 7 8 api: { 9 routes: { 10 [`${API_VERSION}/data`]: "./api/v1/data/route.ts", 11 [`${API_VERSION}/sync`]: "./api/v1/sync/route.ts", 12 }, 13 }, 14};
4. Documentation
Always include comprehensive documentation:
1export const manifest: AppManifest = { 2 assets: { 3 readme: "./README.md", // Detailed setup and usage instructions 4 }, 5 6 settings: { 7 required_metafields: [ 8 { 9 key: "api_key", 10 type: "password", 11 label: "API Key", 12 description: "Get your API key from https://example.com/settings/api", // Clear instructions 13 help_url: "https://docs.example.com/api-key-setup", // Link to documentation 14 }, 15 ], 16 }, 17};
Validation and Testing
Test your manifest configuration:
manifest.test.ts1import { describe, it, expect } from "vitest"; 2import { manifest } from "./manifest"; 3 4describe("App Manifest", () => { 5 it("has valid ID format", () => { 6 expect(manifest.id).toMatch(/^[a-z0-9-]+$/); 7 }); 8 9 it("has semantic version", () => { 10 expect(manifest.version).toMatch(/^\d+\.\d+\.\d+/); 11 }); 12 13 it("has required components", () => { 14 expect(manifest.components.main).toBeDefined(); 15 }); 16 17 it("has valid permissions", () => { 18 const validPermissions = [ 19 "manage_apps", 20 "manage_carriers", 21 "manage_orders", 22 "manage_team", 23 "manage_org_owner", 24 "manage_webhooks", 25 "manage_data", 26 "manage_shipments", 27 "manage_system", 28 ]; 29 30 manifest.permissions.forEach((permission) => { 31 expect(validPermissions).toContain(permission); 32 }); 33 }); 34});
Next Steps
- UI Components - Build your app interface
- API Integration - Connect with Karrio APIs
- Examples - See complete app examples