Installation
This guide will help you install Romancy and set up your development environment.
Prerequisites
- Go 1.24 or higher
Installing Romancy
Add Romancy to your Go project:
go get github.com/i2y/romancyThis installs Romancy with SQLite support, which is perfect for:
- Local development
- Testing
- Single-process deployments
Important: For multi-process or multi-pod deployments (K8s, Docker Compose with multiple replicas, etc.), you must use PostgreSQL or MySQL 8.0+. SQLite supports multiple goroutines within a single process, but its table-level locking makes it unsuitable for multi-process/multi-pod scenarios.
Verifying Installation
Create a test file main.go:
package main
import (
"context"
"fmt"
"log"
"github.com/i2y/romancy"
)
// Result type
type HelloResult struct {
Message string `json:"message"`
}
// Define an activity
var helloActivity = romancy.DefineActivity("hello",
func(ctx context.Context, name string) (string, error) {
return fmt.Sprintf("Hello, %s!", name), nil
},
)
// Define a workflow
var helloWorkflow = romancy.DefineWorkflow("hello_workflow",
func(ctx *romancy.WorkflowContext, name string) (HelloResult, error) {
result, err := helloActivity.Execute(ctx, name)
if err != nil {
return HelloResult{}, err
}
return HelloResult{Message: result}, nil
},
)
func main() {
// Create app with in-memory SQLite
app := romancy.NewApp(
romancy.WithDatabase(":memory:"),
romancy.WithWorkerID("worker-1"),
)
ctx := context.Background()
// Start the app before starting workflows
if err := app.Start(ctx); err != nil {
log.Fatal(err)
}
defer app.Shutdown(ctx)
// Start workflow
instanceID, err := romancy.StartWorkflow(ctx, app, helloWorkflow, "World")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Workflow started: %s\n", instanceID)
// Get result
instance, err := app.Storage().GetInstance(ctx, instanceID)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Result: %v\n", instance.OutputData)
}Run the test:
go run main.goExpected output:
Workflow started: <instance_id>
Result: map[message:Hello, World!]Database Setup
Database Selection
| Database | Use Case | Multi-Worker Support | Production Ready |
|---|---|---|---|
| SQLite | Development, testing, single-process apps | Single-process only | Limited |
| PostgreSQL | Production, multi-process/multi-pod systems | Yes | Yes (Recommended) |
| MySQL 8.0+ | Production, multi-process systems | Yes | Yes |
SQLite (Default)
No additional setup required! SQLite databases are created automatically:
// File-based SQLite (single-process only)
app := romancy.NewApp(
romancy.WithDatabase("workflow.db"),
)
// In-memory (testing only)
app := romancy.NewApp(
romancy.WithDatabase(":memory:"),
)SQLite Considerations:
Supported scenarios:
- Single-process deployments (even with multiple goroutines within that process)
- Development and testing environments
- Low-traffic single-server applications
Not supported:
- Multi-process deployments (Docker Compose with
replicas: 3, multiple systemd services) - Multi-pod deployments (Kubernetes with multiple replicas)
- High-concurrency production scenarios
Performance limitations:
- Table-level locking (not row-level like PostgreSQL or MySQL)
- Concurrent writes are serialized, impacting throughput
- For production with multiple processes/pods, use PostgreSQL or MySQL 8.0+
PostgreSQL
Install PostgreSQL (if not already installed)
Create a database:
CREATE DATABASE romancy_workflows;- Configure connection:
app := romancy.NewApp(
romancy.WithDatabase("postgres://user:password@localhost/romancy_workflows"),
)PostgreSQL Features:
- Row-level locking for concurrent access
- LISTEN/NOTIFY for real-time event delivery (recommended for low latency)
- Supports multi-worker deployments
MySQL 8.0+
Install MySQL 8.0+ (if not already installed)
Create a database:
CREATE DATABASE romancy_workflows;- Configure connection:
app := romancy.NewApp(
romancy.WithDatabase("mysql://user:password@localhost:3306/romancy_workflows"),
)MySQL Requirements:
- MySQL 8.0 or higher required (for
FOR UPDATE SKIP LOCKEDsupport) - Row-level locking for concurrent access
- Supports multi-worker deployments
Database Migrations
Romancy automatically applies database migrations on startup. No manual setup is required!
How It Works
Migration files are embedded in the Romancy binary and applied during app.Start():
app := romancy.NewApp(
romancy.WithDatabase("postgres://user:password@localhost/db"),
)
if err := app.Start(ctx); err != nil { // Migrations run here
log.Fatal(err)
}Features:
- Zero configuration: Works out of the box
- dbmate-compatible: Uses the same
schema_migrationstable as dbmate CLI - Multi-worker safe: Safe for Kubernetes deployments with multiple replicas
- Embedded: No external files needed at runtime
Manual Migration (Optional)
If you prefer to manage migrations externally (e.g., in CI/CD), disable auto-migration:
app := romancy.NewApp(
romancy.WithDatabase("postgres://..."),
romancy.WithAutoMigrate(false), // Disable auto-migration
)Then use dbmate CLI:
# Install dbmate
brew install dbmate # macOS
# Run migrations
dbmate --url "sqlite:workflow.db" --migrations-dir schema/db/migrations/sqlite upFor more details, see the Configuration Reference.
Next Steps
- Quick Start: Build your first workflow in 5 minutes
- Core Concepts: Learn about workflows, activities, and durable execution
- Your First Workflow: Step-by-step tutorial