universal-rendering

Type: pitch
Tags: amigosrenderinguideveloper-experience
Created: Thu Oct 30 2025 00:00:00 GMT+0000 (Coordinated Universal Time)

Universal Rendering System

Automatic UI generation for every Amigos service - write logic, get interfaces free.

The Render() Paradigm

Core Concept

type Renderable interface {
    Render(path string) string
}

Every service can implement Render() to provide automatic UI across all platforms:

Basic Example

type TodoList struct {
    Items []Todo
}

func (t TodoList) Render(path string) string {
    switch runtime.Context() {
    case "terminal":
        return t.renderANSI()
    case "web":
        return t.renderHTML()
    case "api":
        return t.renderJSON()
    default:
        return t.renderMarkdown()
    }
}

Automatic UI Benefits

For Developers

For Users

Implementation Strategy

Phase 1: Basic Rendering

// Amigos provides default renderers
func DefaultRender(v interface{}) string {
    return amigos.AutoFormat(v)
}

Phase 2: Custom Renderers

// Developers can override
func (s Service) Render(path string) string {
    return customHTML(s)
}

Phase 3: Interactive UIs

// Rich interactions
func (s Service) RenderInteractive() Interactive {
    return amigos.UI().
        Form("input", s.handleInput).
        Button("submit", s.handleSubmit)
}

Path-Based Routing

The path parameter enables sub-resource rendering:

func (blog Blog) Render(path string) string {
    switch path {
    case "/":
        return blog.renderIndex()
    case "/posts":
        return blog.renderPosts()
    case matches("/post/*"):
        return blog.renderPost(extractID(path))
    default:
        return "404 Not Found"
    }
}

Format Negotiation

Automatic Detection

// Amigos detects preferred format
Accept: text/html     → HTML output
Accept: application/json → JSON output
Terminal: true        → ANSI output

Explicit Formats

service.Render("/posts.json")  // Force JSON
service.Render("/posts.html")  // Force HTML
service.Render("/posts.md")    // Force Markdown

Built-in Components

Standard UI Elements

// Amigos provides common components
amigos.UI.Table(data)
amigos.UI.Form(fields)
amigos.UI.Chart(metrics)
amigos.UI.Menu(options)

Responsive by Default

Developer Experience

Zero to UI

type Counter struct {
    Value int
}

// That's it! This now has:
// - Web interface at hub.amigos.dev/counter
// - CLI interface via `amigos run counter`
// - API endpoint returning JSON
// - Mobile-responsive design

Custom Styling

func (c Counter) Style() string {
    return `
        .counter { 
            font-size: 48px; 
            color: var(--primary);
        }
    `
}

Integration with Imports

When you import a service, you get its UI too:

import "hub.amigos.dev/blog"

// Your service can embed their UI
func (app App) Render(path string) string {
    if strings.HasPrefix(path, "/blog") {
        return blog.Render(path)
    }
    // ... your rendering
}

Performance Considerations

Server-Side Rendering

Caching Strategy

Future Possibilities

AI-Enhanced Rendering

Visual Programming

Cross-Platform Native

The Philosophy

“Every service is an app, every app is a service”

By making UI generation automatic, we remove the artificial boundary between backend and frontend. Developers focus on logic, users get interfaces.

This isn’t about replacing frontend development - it’s about providing a baseline that works everywhere, allowing custom experiences where needed.

Implementation Priority

  1. Basic Render() - Text/JSON output
  2. HTML Generation - Simple web UIs
  3. Component Library - Reusable UI elements
  4. Interactive Features - Forms and actions
  5. Custom Renderers - Full flexibility

The Render() paradigm transforms Amigos from a platform into an experience - where every piece of logic becomes immediately accessible and usable.

See also

← Back to Knowledge Base