# App Registries

App registries allow you to deploy and distribute Flows apps within your organization or publicly. A registry is simply a collection of JSON files hosted on a web server that describe available apps and their versions.

## Overview
[Section titled “Overview”](#overview)
App registries provide:

 - **Centralized distribution**: Host apps on any web server (S3, GitHub Pages, etc.)
 - **Version management**: Support multiple versions of each app with semantic versioning
 - **Automatic updates**: Flows periodically checks registries for new versions
 - **Checksum verification**: Ensures artifact integrity with SHA-256 checksums

Organizations automatically subscribe to the official Core and Community registries, but you can create and subscribe to custom registries for internal or third-party apps.

## Registry Structure
[Section titled “Registry Structure”](#registry-structure)
A registry consists of two types of JSON files:

 1. **Registry manifest** - The main index file listing all apps
 1. **App metadata files** - Individual files for each app containing version information

### Registry Manifest
[Section titled “Registry Manifest”](#registry-manifest)
The registry manifest is a JSON file at the root URL of your registry:


**

```
{  "apps": {    "my-app": {      "name": "My App",      "description": "A custom app for internal workflows",      "blockStyle": {        "iconUrl": "https://my-registry.example.com/apps/my-app/icon.png",        "color": "#3B82F6"      },      "appMetadataUrl": "https://my-registry.example.com/apps/my-app/versions.json"    },    "another-app": {      "name": "Another App",      "description": "Another useful app",      "blockStyle": {        "iconUrl": "https://my-registry.example.com/apps/another-app/icon.svg",        "color": "#10B981"      },      "appMetadataUrl": "https://my-registry.example.com/apps/another-app/versions.json"    }  }}
```

**Fields:**

 - `apps`: Object mapping app keys to app information
 - **App key**: Unique identifier for the app (used in URLs, must be URL-safe)
 - `name`: Display name shown in the UI
 - `description`: Brief description of the app’s functionality
 - `blockStyle`: Visual styling for the app’s blocks
 - `iconUrl`: URL to the app icon (PNG or SVG)
 - `color`: Hex color code for the block background
 - `appMetadataUrl`: URL to the app’s version metadata file

### App Metadata File
[Section titled “App Metadata File”](#app-metadata-file)
Each app has a metadata file listing its available versions:


**

```
{  "versions": [    {      "version": "1.0.0",      "artifactUrl": "https://my-registry.example.com/apps/my-app/1.0.0.tar.gz",      "artifactChecksum": "sha256:a1b2c3d4e5f6..."    },    {      "version": "1.1.0",      "artifactUrl": "https://my-registry.example.com/apps/my-app/1.1.0.tar.gz",      "artifactChecksum": "sha256:f6e5d4c3b2a1..."    }  ]}
```

**Fields:**

 - `versions`: Array of version objects (order doesn’t matter)
 - `version`: Semantic version string (e.g., “1.2.3”)
 - `artifactUrl`: URL to download the .tar.gz artifact
 - `artifactChecksum`: SHA-256 checksum in the format `sha256:HEX_STRING`

## Creating Your Own Registry
[Section titled “Creating Your Own Registry”](#creating-your-own-registry)
### 1. Choose hosting
[Section titled “1. Choose hosting”](#1-choose-hosting)
You can host your registry on any static file server:

 - **Amazon S3**: Simple, scalable storage with CloudFront CDN
 - **GitHub Pages**: Free hosting for public registries
 - **Azure Blob Storage**: Enterprise-grade storage with CDN
 - **Your own web server**: Any HTTP server can serve JSON files

### 2. Create app artifacts
[Section titled “2. Create app artifacts”](#2-create-app-artifacts)
Build your app artifacts using `flowctl`:


*Terminal window*

```
# Create a tarball of your appflowctl version bundle -e main.ts -o my-app-1.0.0.tar.gz
```

This creates a `.tar.gz` file containing your app code.

### 3. Calculate checksums
[Section titled “3. Calculate checksums”](#3-calculate-checksums)
Generate SHA-256 checksums for your artifacts:


*Terminal window*

```
# macOS/Linuxshasum -a 256 my-app-1.0.0.tar.gz
# Output: a1b2c3d4e5f6... my-app-1.0.0.tar.gz
```

Format the checksum as `sha256:HEX_STRING` for the metadata file.

### 4. Create metadata files
[Section titled “4. Create metadata files”](#4-create-metadata-files)
Create the app metadata file (`versions.json`):


**

```
{  "versions": [    {      "version": "1.0.0",      "artifactUrl": "https://my-registry.example.com/apps/my-app/1.0.0.tar.gz",      "artifactChecksum": "sha256:a1b2c3d4e5f6..."    }  ]}
```

### 5. Create the registry manifest
[Section titled “5. Create the registry manifest”](#5-create-the-registry-manifest)
Create the main registry manifest file:


**

```
{  "apps": {    "my-app": {      "name": "My App",      "description": "Description of my app",      "blockStyle": {        "iconUrl": "https://my-registry.example.com/apps/my-app/icon.png",        "color": "#3B82F6"      },      "appMetadataUrl": "https://my-registry.example.com/apps/my-app/versions.json"    }  }}
```

### 6. Upload files
[Section titled “6. Upload files”](#6-upload-files)
Upload all files to your hosting service:


**

```
my-registry.example.com/├── registry.json              # Main manifest└── apps/    └── my-app/        ├── icon.png           # App icon        ├── versions.json      # App metadata        └── 1.0.0.tar.gz       # App artifact
```

### 7. Configure CORS (if needed)
[Section titled “7. Configure CORS (if needed)”](#7-configure-cors-if-needed)
If hosting on S3 or another origin, configure CORS headers to allow Flows to fetch the files:


**

```
{  "CORSRules": [    {      "AllowedOrigins": ["*"],      "AllowedMethods": ["GET", "HEAD"],      "AllowedHeaders": ["*"]    }  ]}
```

## Example: GitHub Pages Registry
[Section titled “Example: GitHub Pages Registry”](#example-github-pages-registry)
Here’s a complete example using GitHub Pages:

### Repository structure
[Section titled “Repository structure”](#repository-structure)

**

```
my-flows-registry/├── index.json                 # Main manifest (served as root)└── apps/    └── my-app/        ├── icon.svg        ├── versions.json        ├── 1.0.0.tar.gz        └── 1.1.0.tar.gz
```

### index.json
[Section titled “index.json”](#indexjson)

**

```
{  "apps": {    "my-app": {      "name": "My App",      "description": "Internal workflow automation app",      "blockStyle": {        "iconUrl": "https://myorg.github.io/my-flows-registry/apps/my-app/icon.svg",        "color": "#6366F1"      },      "appMetadataUrl": "https://myorg.github.io/my-flows-registry/apps/my-app/versions.json"    }  }}
```

### apps/my-app/versions.json
[Section titled “apps/my-app/versions.json”](#appsmy-appversionsjson)

**

```
{  "versions": [    {      "version": "1.0.0",      "artifactUrl": "https://myorg.github.io/my-flows-registry/apps/my-app/1.0.0.tar.gz",      "artifactChecksum": "sha256:abc123..."    },    {      "version": "1.1.0",      "artifactUrl": "https://myorg.github.io/my-flows-registry/apps/my-app/1.1.0.tar.gz",      "artifactChecksum": "sha256:def456..."    }  ]}
```

### GitHub Pages setup
[Section titled “GitHub Pages setup”](#github-pages-setup)
 1. Create a repository with your registry files
 1. Enable GitHub Pages in repository settings
 1. Set source to the main branch
 1. Access your registry at `https://myorg.github.io/my-flows-registry/index.json`

## Subscribing to a Registry
[Section titled “Subscribing to a Registry”](#subscribing-to-a-registry)
Once your registry is set up, subscribe your organization to it through the Flows UI or API.

### Via UI
[Section titled “Via UI”](#via-ui)
 1. Navigate to **Settings** → **App Registries**
 1. Click **Subscribe to Registry**
 1. Enter your registry URL (e.g., `https://my-registry.example.com/registry.json`)
 1. Provide a name for the registry
 1. Click **Subscribe**

Flows will automatically refresh the registry and make apps available for installation.

### Via API
[Section titled “Via API”](#via-api)

*Terminal window*

```
curl -X POST https://flows.example.com/api/registries/subscribe \  -H "Content-Type: application/json" \  -d '{    "url": "https://my-registry.example.com/registry.json",    "name": "My Internal Registry"  }'
```

## Publishing New Versions
[Section titled “Publishing New Versions”](#publishing-new-versions)
To publish a new version of an app:

 1. **Build the artifact**:


*Terminal window*

```
flowctl version bundle -e main.ts -o my-app-1.2.0.tar.gz
```
 1. **Calculate checksum**:


*Terminal window*

```
shasum -a 256 my-app-1.2.0.tar.gz
```
 1. **Update versions.json**:


**

```
{  "versions": [    {      "version": "1.2.0",      "artifactUrl": "https://my-registry.example.com/apps/my-app/1.2.0.tar.gz",      "artifactChecksum": "sha256:NEW_CHECKSUM"    }  ]}
```
 1. **Upload files**: Upload the new artifact and updated `versions.json`

Flows automatically checks for updates hourly and will discover the new version.

## Best Practices
[Section titled “Best Practices”](#best-practices)
### Security
[Section titled “Security”](#security)
 - **Always use HTTPS**: Protect artifacts and metadata in transit
 - **Verify checksums**: Flows automatically verifies checksums to prevent tampering
 - **Access control**: Use signed URLs or authentication if hosting sensitive apps
 - **CORS configuration**: Only allow necessary origins if possible

### Organization
[Section titled “Organization”](#organization)
 - **Semantic versioning**: Follow SemVer for predictable version management
 - **Immutable artifacts**: Never modify published artifacts; publish new versions instead
 - **Directory structure**: Keep a clean, organized structure for maintainability
 - **Documentation**: Include a README in your registry repository

### Performance
[Section titled “Performance”](#performance)
 - **Use a CDN**: CloudFront, Fastly, or similar for faster global access
 - **Compress artifacts**: Use gzip compression for artifacts (already done by tar.gz)
 - **Cache headers**: Set appropriate cache headers for JSON files (e.g., `Cache-Control: public, max-age=300`)

### Version management
[Section titled “Version management”](#version-management)
 - **Keep all versions**: Don’t delete old versions users may depend on
 - **Document breaking changes**: Note major version changes in descriptions
 - **Test before publishing**: Validate artifacts work before adding to registry
 - **Gradual rollout**: Test new versions in development before promoting

## Official Registries
[Section titled “Official Registries”](#official-registries)
Flows includes two official registries:

 - **Core Registry** (`https://registry.useflows.com/core`): Official apps maintained by Spacelift
 - **Community Registry** (`https://registry.useflows.com/community`): Community-contributed apps

All organizations are automatically subscribed to these registries upon creation.

## Troubleshooting
[Section titled “Troubleshooting”](#troubleshooting)
### Registry not refreshing
[Section titled “Registry not refreshing”](#registry-not-refreshing)
 - Check that your registry URL is accessible via HTTPS
 - Verify CORS headers are configured correctly
 - Ensure JSON files are valid (use a JSON validator)
 - Check Flows logs for specific error messages

### Checksums don’t match
[Section titled “Checksums don’t match”](#checksums-dont-match)
 - Verify you’re using SHA-256 (not SHA-1 or MD5)
 - Ensure the format is exactly `sha256:HEX_STRING` (all lowercase)
 - Check that the artifact file wasn’t modified after checksum calculation
 - Recalculate the checksum and update the metadata

### Icons not displaying
[Section titled “Icons not displaying”](#icons-not-displaying)
 - Verify the icon URL is accessible via HTTPS
 - Check that CORS headers allow the Flows domain
 - Ensure the image format is PNG or SVG
 - Keep icon files under 1MB for best performance

### Apps not appearing
[Section titled “Apps not appearing”](#apps-not-appearing)
 - Verify the app key is URL-safe (alphanumeric, hyphens, underscores)
 - Check that `appMetadataUrl` is correct and accessible
 - Ensure at least one valid version exists in the versions array
 - Validate all version strings follow semantic versioning

## See Also
[Section titled “See Also”](#see-also)
 - [Custom Apps](./custom-apps) - How to create your own apps
 - [Building Apps](../building-apps) - Comprehensive guide to the Flows app SDK
 - [flowctl on GitHub](https://github.com/spacelift-io/flowctl) - CLI tool for building apps