Skip to content

Create Your Own Module

The fastest way to start building your own TinySystems module is to use the example-module template repository. It comes pre-configured with a working component, GitHub Actions CI/CD, and a release script.

Prerequisites

  • Go 1.23+
  • A GitHub account (or any Git hosting with Actions support)
  • A TinySystems account with a workspace

Step 1: Create a Repository from the Template

Go to github.com/tiny-systems/example-module and click Use this template to create a new repository in your GitHub organization or personal account.

my-org/my-awesome-module

Clone your new repository locally:

bash
git clone https://github.com/my-org/my-awesome-module
cd my-awesome-module

Update go.mod to match your repository path:

bash
go mod edit -module github.com/my-org/my-awesome-module

Step 2: Get Your Developer Key

  1. Sign in at tinysystems.io
  2. Create a workspace (or use an existing one)
  3. Go to Workspace Settings and copy your Developer Key

Step 3: Store the Key as a GitHub Secret

In your GitHub repository:

  1. Go to Settings > Secrets and variables > Actions
  2. Click New repository secret
  3. Name: TINY_DEV_SECRET
  4. Value: paste your developer key

TIP

If you have multiple module repos in the same GitHub organization, you can add TINY_DEV_SECRET as an organization secret instead. All repos in the org will share it.

Step 4: Write Your Component

The template includes an echo component at components/echo/echo.go. Use it as a starting point or replace it with your own.

Here's the echo component for reference:

go
package echo

import (
    "context"
    "fmt"

    "github.com/tiny-systems/module/module"
    "github.com/tiny-systems/module/registry"
)

const (
    ComponentName        = "echo"
    InPort        string = "in"
    OutPort       string = "out"
)

type Context any

type InMessage struct {
    Context Context `json:"context" configurable:"true" required:"true" title:"Context" description:"Arbitrary message to be echoed"`
}

type Component struct{}

func (t *Component) Instance() module.Component {
    return &Component{}
}

func (t *Component) GetInfo() module.ComponentInfo {
    return module.ComponentInfo{
        Name:        ComponentName,
        Description: "Echo",
        Info:        "Sends the same message as it receives",
        Tags:        []string{"Echo", "Demo"},
    }
}

func (t *Component) Handle(ctx context.Context, handler module.Handler, port string, msg any) any {
    in, ok := msg.(InMessage)
    if !ok {
        return fmt.Errorf("invalid message")
    }
    return handler(ctx, OutPort, in.Context)
}

func (t *Component) Ports() []module.Port {
    return []module.Port{
        {
            Name:          InPort,
            Label:         "In",
            Configuration: InMessage{},
            Position:      module.Left,
        },
        {
            Name:          OutPort,
            Label:         "Out",
            Source:        true,
            Configuration: new(Context),
            Position:      module.Right,
        },
    }
}

var _ module.Component = (*Component)(nil)

func init() {
    registry.Register(&Component{})
}

To add more components, create a new package under components/ and register it with a blank import in cmd/main.go:

go
import (
    _ "github.com/my-org/my-awesome-module/components/echo"
    _ "github.com/my-org/my-awesome-module/components/mycomponent"
)

Step 5: Publish with a Git Tag

The template includes a GitHub Actions workflow (.github/workflows/release.yml) that automatically builds and publishes your module when you push a semver tag:

bash
git tag v0.0.1
git push origin v0.0.1

A convenience script is also included:

bash
./release.sh        # interactive - asks for patch/minor/major
./release.sh patch  # direct bump

What Happens on Tag Push

  1. GitHub Actions checks out your code
  2. Runs go run cmd/main.go tools build with your version and developer key
  3. The SDK introspects all registered components and generates JSON schemas for their ports
  4. Module metadata is published to the TinySystems platform
  5. A container image is built and pushed to the platform's registry

The workflow file (.github/workflows/release.yml):

yaml
name: Build & publish module to the Tiny Systems

on:
  push:
    tags:
      - 'v[0-9]+.[0-9]+.[0-9]+'
jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-go@v5
        with:
          go-version: '>=1.23.1'
      - run: |
          go mod tidy
          go run cmd/main.go tools build \
            --version ${{github.ref_name}} \
            --name github.com/${{ github.repository }} \
            --devkey ${{secrets.TINY_DEV_SECRET}}

Step 6: Install Your Module

Once the GitHub Actions workflow completes, your module appears in your workspace's module list on tinysystems.io. From there you can install it into any connected cluster with one click.

Your components will show up in the visual editor's component palette, ready to use in flows.

Updating the SDK

To update to the latest SDK version:

bash
./release.sh update
# or manually:
go get github.com/tiny-systems/module@latest
go mod tidy

Project Structure

my-awesome-module/
├── cmd/
│   └── main.go                          # Entry point, component registration
├── components/
│   └── echo/
│       └── echo.go                      # Component implementation
├── .github/
│   └── workflows/
│       └── release.yml                  # CI/CD pipeline
├── release.sh                           # Release helper script
├── go.mod
└── README.md

Next Steps

Build flow-based applications on Kubernetes