FlickDocumentation
flkr

Quick start

Create, edit, and publish Flick views from the command line.

flkr connects your app’s Swift view declarations to TypeScript components. In this guide, you’ll publish a card that receives a title from Swift and renders Hello from Flick in your app.

Start with the MyApp.Views.Card declaration and mount from the Swift quick start. These examples use the same app, MyApp, and bundle ID, com.acme.myapp.

1. Install flkr

Requires Node.js 24 or later.

npm install -g @flickfyi/flkr

2. Sign in to Flick

Run flkr from your home directory:

cd ~
flkr

Sign-in connects flkr to your Flick account so it can publish development updates.

  1. Press L to open the Link Device page in your browser.
  2. Sign in with Google, then click Authorize CLI.
  3. When the browser shows CLI Authorized, return to the terminal. Once your account appears, press Q to quit flkr.

flkr saves your credentials in macOS Keychain and signs you in automatically the next time you run it.

3. Start in development mode

MyApp/MyAppApp.swift
// Skip trust-root verification during development
FlickSDK(trustRoot: nil) {
    ContentView()
}
MyApp/MyApp+Flick.swift
import FlickSDK

// Leave the URL off so flkr publishes with your signed-in account during development
@FlickScope
// Namespace for your app's actions, state, and views
enum MyApp {
    // Expose Swift operations that Flicks can invoke
    enum Action {
        // @FlickAction(failure: FlickContextError.self)
        // @FlickAction(output: .effect(Int.self))
        // case increment(by: Int)

        // In your SwiftUI view: @State var count = 0
        @FlickAction(failure: Never.self)
        case increment // -> .taskForFlick(for: \.increment) { count += 1 }
    }

    // Expose Swift state for Flick observation
    enum State {
        // In your SwiftUI view: @State var count = 0
        case count(Int) // -> .observeForFlick(count, for: \.count) { Flick.Publish($0) }
    }

    // Mount Flicks as SwiftUI views with inputs from Swift
    enum Views {
        // -> Flick(.card, title: "Hello")
        struct Card: Codable, Sendable {
            let title: String
        }
    }
}

On your Mac, run flkr from the directory containing your app’s .xcodeproj:

MyApp/
flkr

flkr runs the generator included in your app’s Swift SDK, then opens a list of its named views.

MyApp — flkr

~/MyApp ❯ flkr

com.acme.myapp · Views

↑↓ select · enter open/create · p publish · r refresh · l login · q quit

Development · watching files · save to publish

▸ card not implemented

Select card with ↑ / ↓, and press Enter to create flicks/src/card.tsx and open it in your editor. Your project now contains:

Project layout
MyApp/
├── MyApp.xcodeproj
├── MyApp/
│   ├── ContentView.swift
│   ├── MyAppApp.swift
│   └── MyApp+Flick.swift
├── generated/
│   ├── manifest.json
│   ├── package.json
│   └── src/
│       ├── index.js
│       ├── index.d.ts
│       └── FlickContext+Generated.swift
└── flicks/
    ├── package.json
    ├── tsconfig.json
    └── src/
        └── card.tsx

Edit your components in flicks/src/. The generated/ package contains the JavaScript exports, TypeScript types, and Swift loader produced from your app’s declarations.

flkr also creates flicks/package.json and flicks/tsconfig.json with the required dependencies and compiler settings. Press Q to leave flkr, then install those dependencies:

cd flicks
npm install
cd ..

4. Edit the implementation

Run flkr again from the app directory after installing dependencies. Your saved sign-in enables file watching.

MyApp — flkr

~/MyApp ❯ flkr

com.acme.myapp · Views

↑↓ select · enter open/create · p publish · r refresh · l login · q quit

Development · watching files · save to publish

▸ card src/card.tsx

The mount from the Swift quick start supplies the title input:

MyApp/ContentView.swift
import FlickSDK
import SwiftUI

struct ContentView: View {
    var body: some View {
        Flick(.card, title: "Hello")
    }
}

Replace the contents of flicks/src/card.tsx with a component that uses that title:

flicks/src/card.tsx
import { defineView, Text } from '@flickfyi/core'

// Flick SDK's Swift parser generates this package from your annotated MyApp enum
// It lives in generated/ and is named after your app's bundle ID
// flkr links it as "com.acme.myapp": "file:../generated" in flicks/package.json
import { MyApp } from 'com.acme.myapp'

// MyApp.views.card is generated from the Swift declaration MyApp.Views.Card
// defineView infers { title: string } from its type in generated/src/index.d.ts
export default defineView(MyApp.views.card, ({ title }) => {
  return <Text>{title} from Flick</Text>
})

flkr finds .ts and .tsx files under flicks/src/ using flicks/tsconfig.json. The defineView binding identifies each view, so renaming its file keeps the connection to Swift.

Save the file. flkr compiles and publishes your implemented views, including changes to shared components. Build and run your app in Xcode: the card displays Hello from Flick.

Keep flkr and your app running while you edit. Each saved change updates the mounted view. Compilation errors appear in the terminal; the app keeps its last published version until the code compiles successfully.

Publish with PKI

Development publications use your signed-in identity. PKI adds proof that your app’s root authority approved an update, so the app can select publications authorized by that authority.

Set your trust-root URL on @FlickScope and use FlickSDK { … } to enable that selection:

MyApp/MyApp+Flick.swift
@FlickScope(url: "https://acme-corp.com")
enum MyApp {
    // Your existing Action, State, and Views declarations…
}

Set up public-key infrastructure

Follow the PKI guide to save your root key in 1Password and publish its public key. Use the trust-root URL from your app’s @FlickScope declaration to check key discovery below.

Install the 1Password CLI, sign in to the 1Password app, and enable Settings → Developer → Integrate with 1Password CLI.

By default, flkr reads your Base58 root private key from op://Private/Flick SDK Root Authority/password. Save it there, then run this command and approve the 1Password prompt to print the stored value:

op read "op://Private/Flick SDK Root Authority/password"

From the directory containing MyApp.xcodeproj, run:

MyApp/
flkr publish

flkr creates a one-hour Biscuit delegation from the root key. The server discovers your public key and verifies the delegation before accepting the publication.

flkr refreshes the generated types, type-checks your components, and publishes all declared views. Each declared view must have an implementation.

With PKI configured, publishing is explicit: run flkr publish or press P in the view list. Your running app receives each authorized update.

Edit and publish again

Use these shortcuts in flkr’s view list:

KeyAction
↑ / ↓Select a view
EnterCreate or open its implementation
LSign in for development publishing
PPublish the selected view
RRefresh the list after editing files
QQuit

After changing Swift declarations, quit and reopen flkr to regenerate the types. flkr installs a Generate Flick SDK build phase so Xcode builds also refresh generated/.

Commit generated/, the Xcode project changes, and flicks/ sources together.

For automated publishing, see Continuous integration.