UP (Unified Properties)

A Human-Friendly Data Serialization Format

View the Project on GitHub uplang/spec

Version 2.0.0 - Templating System (2025-10-05)

⚠️ Important: Syntax Clarification

Multi-word values MUST be quoted in UP.

UP is whitespace-delimited, so:

See SYNTAX-REFERENCE.md for complete quoting rules.

Fixed in this release:

Note: Some documentation examples may still need updating. When in doubt, quote multi-word values.

Multiline string best practice:

# BAD - breaks indentation
metadata {
  notes ```
Content not indented

}

GOOD - maintains structure

metadata { notes!2 Content properly indented }


### 🎉 Major New Feature: Templating

Declarative configuration composition using `!annotation` syntax, consistent with UP's type system.

#### Template Annotations

- `config!base file` - Inherit from base configuration
- `key!overlay { }` - Declarative merge
- `key!include [...]` - Compose from multiple files
- `key!patch { }` - Targeted modifications
- `key!merge { }` - Configure merge strategies
- `$vars.path` - Variable references

#### New CLI Commands

```bash
up template process -i template.up -o output.up
up template validate -i template.up

Key Design

Multi-Document Support

Example:

# base config
vars { port!int 8080 }

# ---

# dev config
server!overlay { debug!bool true }

# ---

# prod config
server!overlay { replicas!int 10 }

Iterative Variable Resolution

Example:

vars {
  region us-west-2
  environment production
  host $vars.environment.$vars.region.example.com
  url https://$vars.host:443/api
  health $vars.url/health
}
# All variables resolve correctly regardless of order

UP-JSON Relationship

New UP-JSON.md document explains:

Key innovation: Two types of maps

Dynamic Variable Namespaces (Design)

New DYNAMIC-NAMESPACES.md specification for dynamic content generation:

Pragma-based opt-in:

!use [time, id, faker, random]

Reserved namespaces:

Use cases:

Design principles:

Pluggable Namespace System (Design)

New NAMESPACE-PLUGINS.md specification for extensible namespaces:

Any executable can be a namespace:

#!/bin/bash
# ./up-namespaces/greeting

INPUT=$(cat)
FUNCTION=$(echo "$INPUT" | jq -r '.function')
NAME=$(echo "$INPUT" | jq -r '.params.positional[0] // "World"')

case "$FUNCTION" in
  hello)
    echo "{\"value\": \"Hello, $NAME!\", \"type\": \"string\"}"
    ;;
esac

UP schemas describe namespaces:

# greeting.up-schema
namespace greeting
version 1.0.0

functions {
  hello {
    description Generate a hello greeting
    params {
      name!string {
        default World
        required!bool false
      }
    }
    returns!string {
      example Hello, Alice!
    }
  }
}

Plugin protocol:

Benefits:

UP schemas are UP - schemas all the way down!

Namespace Security & Versioning (Design)

New NAMESPACE-SECURITY.md specification for secure, reproducible namespaces:

Version pinning:

# Exact version
!use [greeting@1.2.3]

# Version range
!use [greeting>=1.0.0,<2.0.0]

# Compatible versions
!use [greeting^1.2.0]

Lock file (up-namespaces.lock):

namespaces {
  greeting {
    version 1.2.3
    files {
      executable {
        hash sha256:a3b5c9d1e2f4567890abcdef...
      }
    }
    verified!bool true
  }
}

Security features:

Security policy:

policy {
  verify_hashes!bool true
  require_signatures!bool true
  fail_on_hash_mismatch!bool true
}

namespace_policies {
  dangerous {
    namespaces [file, env, exec]
    require_explicit_approval!bool true
    require_signature!bool true
  }
}

Benefits:

Runtime Schema Validation (Design)

New SCHEMA-VALIDATION.md specification for type-safe validation:

Types reference schemas:

# File-based schema
server!file://./schemas/server.up-schema {
  host localhost
  port!int 8080
}

# URL-based schema
config!https://schemas.uplang.org/config/1.0.0 {
  environment production
}

# Type mapping (via .up-schemas)
user!user {
  name "Alice"
  email alice@example.com
}

Schemas written in UP:

schema server
version 1.0.0

fields {
  host!string {
    required!bool true
    pattern ^[a-zA-Z0-9.-]+$
  }

  port!int {
    required!bool true
    min 1
    max 65535
  }
}

validation {
  rules [
    {
      condition "port == 443"
      requires "tls_enabled == true"
      error "Port 443 requires TLS"
    }
  ]
}

CLI integration:

# Parse with validation (default)
up parse -i config.up

# Skip validation
up parse -i config.up --no-validate

# Strict mode
up validate -i config.up --strict

Features:

Benefits:

Namespace Aliases

Support for aliasing namespaces to use multiple versions or implementations simultaneously.

Syntax:

!use [namespace as alias]
!use [namespace@version as alias]
!use [url as alias]

Examples:

# Multiple versions for migration
!use [time, time@1.0.0 as oldtime, time@2.0.0 as newtime]

current $time.now
legacy $oldtime.now
enhanced $newtime.now
# Different implementations
!use [
  github.com/uplang/ns-random as random,
  github.com/myorg/secure-random as securerandom
]

session_id $random.uuid
api_key $securerandom.bytes(size=32)

Use Cases:

Documentation:

📦 Project Reorganization

📚 Documentation

📁 New Example Templates

Created comprehensive templating examples:

Base & Environments:

Feature Modules:

Composed Configurations:

All templates successfully validated! ✅

🔧 Implementation

🎯 Use Cases

UP templating is perfect for:

  1. Multi-environment configuration - Base + environment-specific overlays
  2. Feature flag composition - Mix and match features
  3. Infrastructure as Code - Kubernetes configs, Terraform variables
  4. Configuration management - Ansible, Chef, Puppet alternatives
  5. CI/CD pipelines - GitLab CI, GitHub Actions, Jenkins

📊 Comparison with Other Systems

Feature UP Helm Kustomize Jsonnet
Syntax Native UP Go Templates YAML Jsonnet DSL
Type Safety ⚠️
Learning Curve Low High Medium High
Logic in Templates
Declarative ⚠️
Multi-Language

🚀 Breaking Changes

Go module paths changed:

🔮 Future Plans

Next Release (v2.1.0)

Future Releases


Version 1.0.0 - Initial Release

Features