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