Quick Start

This is the shortest end-to-end path to create a TypeScript pipe worker from scratch.

Commands used

mkdir -p /tmp/worker-quick-start
cd /tmp/worker-quick-start
npm install @industream/flowmaker-worker-scripts
npx worker-cli init
npx worker-cli create --type node --name hello-world --box-type pipe --icon code --display-name "Hello World" --no-build
cd workers/hello-world/frontend
npx flowbox-ui init
npx flowbox-ui add default
cd /tmp/worker-quick-start
# create/edit workers/hello-world/README.md manually
# open .env and type REGISTRY and IMAGE_PREFIX manually
npx worker-cli consistency hello-world
npx worker-cli build hello-world

Real terminal transcript (ASCII)

1) Install CLI package

$ npm install @industream/flowmaker-worker-scripts

Install output omitted for readability.

2) Initialize a new worker repository

$ npx worker-cli init

Creates the repository skeleton and workers directory.

Initializing FlowMaker workers repository...
Target directory: /tmp/worker-quick-start
Templates directory: /tmp/worker-quick-start/node_modules/@industream/flowmaker-worker-scripts/templates/init
šŸ“„ Copying file: .gitattributes
šŸ“ Copying directory: AGENTS/
šŸ“„ Copying file: README.md
šŸ“„ Copying file: README.repo-guidelines.md
šŸ“ Created directory: workers/
āœ… Repository initialized successfully!

3) Create a TypeScript pipe worker (hello-world)

$ npx worker-cli create --type node --name hello-world --box-type pipe --icon code --display-name "Hello World" --no-build

Generates backend worker files for hello-world.

Creating worker (non-interactive):
  Type:         node
  Name:         hello-world
  Display name: Hello World
  Box type:     pipe
  Icon:         code

Generating worker...

āœ“ package.json
āœ“ tsconfig.json
āœ“ Dockerfile
āœ“ index.ts
āœ“ version.js
āœ“ version.d.ts

4) Initialize FlowBox UI frontend (successful run)

$ cd workers/hello-world/frontend
$ npx flowbox-ui init
$ npx flowbox-ui add default
$ cd /tmp/worker-quick-start

Completes frontend scaffolding required by the Docker build (frontend/package.json, frontend/src/default/*). When prompted for package manager, type npm and press Enter.

Initializing FlowBox UI project...

Package manager (npm/pnpm/yarn/bun) [npm]: 
Installing dependencies...

added 41 packages, and audited 42 packages in 4s

6 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

added 1 package, and audited 43 packages in 930ms

6 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities

Project initialized!
Next: npx flowbox-ui add <component-name>

Creating component: default...

Created src/default/
  - main.js
  - ConfigForm.svelte

Build with: npm run build
Dev server: npx flowbox-ui start default

5) Add README, set .env, and run consistency check

$ npx worker-cli consistency hello-world

Before running this check, create workers/hello-world/README.md and set .env interactively with REGISTRY=registry.example.com and IMAGE_PREFIX=myteam/.

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Consistency Check
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  - hello-world
    āœ“ node v1.0.0

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
āœ“ All workers passed consistency check
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

6) Build Docker image

$ npx worker-cli build hello-world

Starts pre-checks and Docker Buildx build for the worker image.

Running pre-build checks...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Consistency Check
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  - hello-world
    āœ“ node v1.0.0

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
āœ“ All workers passed consistency check
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

āœ“ npm caching proxy running on port 4873
āœ“ npm proxy reachable at 172.17.0.1:4873 from build stages
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Building hello-world
   Version:   1.0.0
   Image:     registry.example.com/myteam/hello-world:1.0.0
   Platforms: linux/amd64,linux/arm64
   Target:    Load locally (current arch only)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
āœ“ Built registry.example.com/myteam/hello-world:1.0.0 (loaded locally)

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Testing hello-world v1.0.0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Starting mock config-hub on port 3120...
Running container registry.example.com/myteam/hello-world:1.0.0...

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Registration Results:
  āœ“ industream/hello-world v1.0.0
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
āœ“ All 1 box(es) registered with correct version v1.0.0

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Done!

After generating a TypeScript worker, this is the default structure you will end up with. Keep the worker root small (max 15 entries), keep implementation files under src/, and always include a README.md in the worker folder.

Worker structure (frontend + backend)

workers/hello-world/
ā”œā”€ā”€ Dockerfile
ā”œā”€ā”€ package.json
ā”œā”€ā”€ tsconfig.json
ā”œā”€ā”€ README.md
ā”œā”€ā”€ src/
│   ā”œā”€ā”€ index.ts
│   ā”œā”€ā”€ version.d.ts
│   └── version.js
└── frontend/
    └── src/default/
        ā”œā”€ā”€ ConfigForm.svelte
        └── main.js

Backend files were generated in the real run; the frontend path above is the expected FlowBox UI structure.

FlowBoxRegistration extract (backend)

Source file: /tmp/worker-quick-start/workers/hello-world/src/index.ts

...
@FlowBoxRegistration({
    id: "industream/hello-world",
    displayName: "Hello World",
    currentVersion: version,
    type: "pipe",
    icon: "code",
    stateless: true,
    agent: "flowmaker-node/1.0.0;os=linux;tag=docker;",
    workerId: workerId,
    workerDataConnectionString: process.env['FM_WORKER_TRANSPORT_ADV_ADDRESS'] || 'tcp://localhost:5560',
    ioInterfaces: {
        inputs: [{ name: "default", displayName: "Default", supportedFormats: ["msgpack"] }],
        outputs: [{ name: "default", displayName: "Default", supportedFormats: ["msgpack"] }],
    },
    uiConfig: {
        type: "js-bundle",
        defaultOptions: {
            example: ""
        },
        implementation: _getConfigImplementation()
    }
})
...

onInputReceived extract (backend)

Source file: /tmp/worker-quick-start/workers/hello-world/src/index.ts

...
public onInputReceived(inputId: Buffer, header: Buffer, data: Buffer, fnReadyForNextItem: () => any): void {
    const parsed = unpack(data);
    console.log(`Received input: ${JSON.stringify(parsed)}`);
    fnReadyForNextItem();
}
...

Frontend ConfigForm.svelte input extract

Source file: /tmp/worker-quick-start/workers/hello-world/frontend/src/default/ConfigForm.svelte

...
<script>
    import { flowMakerBridge, getValue } from '@industream/flowmaker-flowbox-ui';

    const props = $props();
    const { context, values, validity, emit } = flowMakerBridge(props);

    const onInputChange = (e) => {
        $values.myField = getValue(e);
        emit('values', $values);
    };
</script>

<cds-text-input
    label="My Field"
    value={$values?.myField ?? ''}
    oninput={onInputChange}>
</cds-text-input>
...

Notes

  • Package name is @industream/flowmaker-worker-scripts.
  • Transcript captured from a real run in /tmp/worker-quick-start.
  • Docker build and registration check completed successfully in this environment after initializing frontend/ with flowbox-ui.

References

  • workers/hello-world/src/index.ts
  • sdk/config/flowbox-ui/templates/component/ConfigForm.svelte
  • sdk/worker/repo-management/src/commands/build.ts