Skip to content

Custom Apps

Custom apps allow you to extend Flows with your own functionality by writing TypeScript/JavaScript code that implements the Flows app SDK. This guide covers how to create, develop, and deploy custom apps using flowctl, the official CLI tool for Flows app development.

  • Node.js 18 or later
  • A Flows account with appropriate permissions
  • Basic knowledge of TypeScript/JavaScript

Install the flowctl CLI globally using npm:

Terminal window
npm install -g @useflows/flowctl

Verify the installation:

Terminal window
flowctl --version

Before creating or managing apps, authenticate with Flows:

Terminal window
flowctl auth login

This will open your browser to complete the authentication flow. Once authenticated, you can manage apps and versions.

To logout:

Terminal window
flowctl auth logout

Create a new app in Flows:

Terminal window
flowctl app create

This command will prompt you for:

  • App name: Display name for your app
  • Description: Brief description of what your app does
  • Block color: Color theme for your app’s blocks (e.g., #3B82F6)
  • Icon URL: Optional URL to an icon for your app
  • Project ID: Optional project to associate the app with (use -p flag to specify)

The command creates the app and returns an app ID that you’ll use for version management.

Create a TypeScript file (e.g., main.ts) that defines your app using the Flows SDK:

import { defineApp, events } from "@slflows/sdk/v1";
export default defineApp({
name: "Hello World App",
config: {
message: {
name: "Greeting Message",
type: "string",
required: true,
default: "Hello, World!",
},
},
blocks: {
greeter: {
name: "Greeter",
description: "Emits a greeting message",
outputs: {
default: {
name: "Greeting",
description: "The greeting message",
type: "string",
},
},
schedules: {
greet: {
description: "Send greeting every hour",
definition: {
type: "frequency",
frequency: {
interval: 1,
unit: "hours",
},
},
onTrigger: async (input) => {
await events.emit({
message: input.app.config.message,
timestamp: new Date().toISOString(),
});
},
},
},
},
},
});

Create an initial version of your app:

Terminal window
flowctl version create -e main.ts

Options:

  • -e, --entrypoint: Path to your app’s entry file (required)
  • -a, --app: App ID (if not specified, will prompt or use the most recent)
  • -v, --version: Version number (if not specified, will prompt for SemVer bump)
  • --ui-entrypoint: Optional path to UI entry file for custom interfaces

The version is created in draft state, which means it’s not yet visible to users.

During development, use watch mode to automatically update your draft version when files change:

Terminal window
flowctl version update -e main.ts --watch

This monitors your files and automatically uploads changes to the draft version, enabling rapid iteration.

When your app is ready, publish the draft version to make it available:

Terminal window
flowctl version publish

This makes the version visible and installable in Flows.

A Flows app consists of several key components:

  • name: Display name shown in the UI
  • installationInstructions: Markdown text shown during installation
  • config: Configuration fields set during installation
  • signals: Values exposed by the app to blocks

Blocks are the entities users place on the canvas. Each block can have:

  • Inputs: Receive events from other blocks
  • Outputs: Emit events to other blocks
  • Config: Block-specific configuration fields
  • Lifecycle: onSync and onDrain handlers for state management
  • HTTP: Handle incoming HTTP requests
  • Schedules: Periodic or cron-based triggers
  • Timers: Handle one-time delayed execution
  • onSync: Called when the app needs to synchronize (e.g., provision resources)
  • onDrain: Called when the app is being removed (cleanup)
  • onInternalMessage: Receive messages from blocks
  • onTimer: Handle app-level timers
  • http.onRequest: Handle app-level HTTP requests

See the Building Apps section for comprehensive documentation on all app components and services.

Flows apps use semantic versioning (SemVer): MAJOR.MINOR.PATCH

  • MAJOR: Breaking changes
  • MINOR: New features, backwards compatible
  • PATCH: Bug fixes, backwards compatible

Create a new version with an explicit version number:

Terminal window
flowctl version create -e main.ts -v 1.2.0

Or use interactive SemVer bump selection:

Terminal window
flowctl version create -e main.ts
# Will prompt: major, minor, or patch?

View all versions of an app:

Terminal window
flowctl version list -a <app-id>

When you create a version, it starts as a draft:

  1. Create: flowctl version create - Creates a draft version
  2. Develop: flowctl version update --watch - Iterate on the draft
  3. Publish: flowctl version publish - Make it available to users

Draft versions are only visible to developers and are not installable by users.

By default, apps are scoped to a specific project:

Terminal window
flowctl app create -p my-project-id

Project-scoped apps are only visible within that project.

To make an app available across your entire organization, create it without specifying a project, or contact your Flows administrator to promote an existing project-scoped app to organization-wide visibility.