Skip to content

Module Scaffold

The CLI provides scaffolding commands to quickly create new modules with the correct structure and boilerplate code.

Creating a New Module

Basic Module

bash
tinysystems init my-module

This creates a new module with:

my-module/
├── cmd/
│   └── main.go              # Entry point
├── components/              # Component directory
├── go.mod                   # Go module
├── go.sum
├── Dockerfile              # Container build
├── Makefile                # Common tasks
├── .tinysystems.yaml       # CLI config
└── README.md               # Documentation

With Go Module Path

bash
tinysystems init my-module --go-module github.com/myorg/my-module

From Template

bash
# List available templates
tinysystems init --list-templates

# Use specific template
tinysystems init my-module --template advanced

Project Structure

cmd/main.go

go
package main

import (
    "github.com/tiny-systems/module/module"
    "github.com/myorg/my-module/components/example"
)

func main() {
    mod := module.NewWithComponents(
        &example.Component{},
    )

    if err := mod.Run(); err != nil {
        panic(err)
    }
}

Dockerfile

dockerfile
# Build stage
FROM golang:1.21-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o module ./cmd/main.go

# Runtime stage
FROM alpine:3.18

WORKDIR /app
COPY --from=builder /app/module .

ENTRYPOINT ["/app/module"]

Makefile

makefile
.PHONY: build run test lint

MODULE_NAME := my-module
VERSION := $(shell git describe --tags --always --dirty)
REGISTRY := my-registry.io

build:
	go build -o bin/module ./cmd/main.go

run:
	go run ./cmd/main.go

test:
	go test -v ./...

lint:
	golangci-lint run

docker-build:
	docker build -t $(REGISTRY)/$(MODULE_NAME):$(VERSION) .

docker-push: docker-build
	docker push $(REGISTRY)/$(MODULE_NAME):$(VERSION)

generate:
	go generate ./...

helm-package:
	helm package charts/$(MODULE_NAME)

.tinysystems.yaml

yaml
module:
  name: github.com/myorg/my-module
  version: 1.0.0
  description: My custom module

build:
  registry: my-registry.io
  image: my-module

development:
  port: 50051
  namespace: tinysystems-dev
  watch:
    - "**/*.go"
    - "!**/*_test.go"

deployment:
  namespace: tinysystems
  replicas: 2
  resources:
    requests:
      cpu: 100m
      memory: 128Mi
    limits:
      cpu: 500m
      memory: 512Mi

Adding Components

Generate Component

bash
cd my-module
tinysystems generate component transformer

Creates:

components/transformer/
├── component.go       # Main implementation
├── types.go          # Type definitions
└── component_test.go # Tests

Register Component

Update cmd/main.go:

go
package main

import (
    "github.com/tiny-systems/module/module"
    "github.com/myorg/my-module/components/example"
    "github.com/myorg/my-module/components/transformer"
)

func main() {
    mod := module.NewWithComponents(
        &example.Component{},
        &transformer.Component{},  // Add new component
    )

    if err := mod.Run(); err != nil {
        panic(err)
    }
}

Template Types

Basic Template

Minimal module with one example component:

bash
tinysystems init my-module --template basic
  • Single component example
  • Minimal configuration
  • Basic Dockerfile

Advanced Template

Full-featured module setup:

bash
tinysystems init my-module --template advanced
  • Multiple component examples
  • GitHub Actions CI/CD
  • Helm chart
  • Comprehensive documentation

Server Template

For HTTP-serving modules:

bash
tinysystems init my-api --template server
  • HTTP server component
  • Ingress configuration
  • Health endpoints
  • TLS setup

Customizing Scaffolds

Custom Templates

Create .tinysystems/templates/ in your home directory:

~/.tinysystems/templates/
├── myorg-basic/
│   ├── template.yaml
│   ├── cmd/main.go.tmpl
│   └── components/example/component.go.tmpl

Use with:

bash
tinysystems init my-module --template myorg-basic

Template Variables

Templates support Go template syntax:

go
// component.go.tmpl
package {{.ComponentName}}

import (
    "github.com/tiny-systems/module/module"
)

type Component struct{}

func (c *Component) GetInfo() module.Info {
    return module.Info{
        Name:        "{{.ComponentName | kebab}}",
        Description: "{{.Description}}",
    }
}

Best Practices

1. Use Meaningful Names

bash
# Good
tinysystems init data-transformer
tinysystems generate component csv-parser

# Avoid
tinysystems init module1
tinysystems generate component comp

2. Organize by Feature

components/
├── input/        # Input-related components
│   ├── http-receiver/
│   └── file-reader/
├── transform/    # Transformation components
│   ├── json-parser/
│   └── filter/
└── output/       # Output components
    ├── http-sender/
    └── file-writer/

3. Include Tests

Always generate tests with components:

bash
tinysystems generate component my-component
# Includes component_test.go

4. Document Components

Add README.md to each component:

components/transformer/
├── component.go
├── types.go
├── component_test.go
└── README.md    # Document purpose, usage, examples

Next Steps

Build flow-based applications on Kubernetes