Configuration Management

Human-readable configs with schema validation. A modern alternative to YAML, JSON, or TOML.

Why Tauq for Configuration?

📝

Human Readable

Clean syntax without excessive punctuation. Easy to read and write.

💬

Comments

Full comment support with # syntax. Document your configuration inline.

🔗

Imports

Split configs across files with !import. Keep things organized.

Format Comparison

YAML

server:
  host: localhost
  port: 8080
  ssl:
    enabled: true
    cert: /etc/ssl/cert.pem

database:
  host: db.example.com
  port: 5432
  name: myapp
  pool_size: 10

features:
  - auth
  - logging
  - metrics

Indentation-sensitive, easy to break

Tauq

# Server configuration
server {
  host localhost
  port 8080
  ssl {
    enabled true
    cert /etc/ssl/cert.pem
  }
}

# Database settings
database {
  host db.example.com
  port 5432
  name myapp
  pool_size 10
}

# Enabled features
features [auth logging metrics]

Explicit braces, impossible to break with whitespace

Real-World Examples

Application Config

# app.tqn - Main application configuration
app_name "MyService"
version "2.1.0"
environment production

# Server settings
server {
  host 0.0.0.0
  port 8080
  workers 4
  timeout_ms 30000
}

# Logging configuration
logging {
  level info
  format json
  outputs [stdout file]
  file_path /var/log/myservice.log
}

# Feature flags
features {
  new_dashboard true
  beta_api false
  dark_mode true
}

Docker Compose Alternative

# services.tqn - Service definitions
!def Service name image ports env

# Define services as records
!use Service
web nginx:latest [80:80 443:443] { NODE_ENV production }
api myapp:v2.1 [3000:3000] { DATABASE_URL "postgres://..." }
redis redis:7-alpine [6379:6379] {}
postgres postgres:15 [5432:5432] { POSTGRES_DB myapp }

# Networks
networks [frontend backend]

# Volumes
volumes [postgres_data redis_data]

CI/CD Pipeline

# pipeline.tqn - Build pipeline configuration
name "Build and Deploy"
trigger {
  branches [main develop]
  paths [src/** tests/**]
}

!def Stage name runs_on steps

stages [
  !use Stage

  build ubuntu-latest [
    { name "Checkout" run "git checkout" }
    { name "Install" run "npm ci" }
    { name "Build" run "npm run build" }
    { name "Test" run "npm test" }
  ]

  deploy ubuntu-latest [
    { name "Deploy" run "npm run deploy" }
    { name "Notify" run "curl -X POST $SLACK_WEBHOOK" }
  ]
]

Modular Configuration

Split Configs with !import

Keep your configuration organized by splitting into multiple files.

config/main.tqn
# Main configuration - imports other files
!import ./database.tqn
!import ./server.tqn
!import ./features.tqn

app_name "MyService"
version "2.1.0"
config/database.tqn
database {
  host db.example.com
  port 5432
  name myapp
  pool_size 10
}
config/server.tqn
server {
  host 0.0.0.0
  port 8080
  workers 4
}

Environment-Specific Configs

# config/base.tqn - Shared settings
app_name "MyService"
logging { level info format json }

# config/dev.tqn
!import ./base.tqn
environment development
server { host localhost port 3000 }
database { host localhost }

# config/prod.tqn
!import ./base.tqn
environment production
server { host 0.0.0.0 port 8080 workers 8 }
database { host db.prod.example.com pool_size 20 }

Loading Configuration

Python

import tauq

# Load configuration
config = tauq.load('config/main.tqn')

# Access values
print(config['app_name'])        # "MyService"
print(config['server']['port'])  # 8080
print(config['features'])        # ["auth", "logging", "metrics"]

# With validation
from dataclasses import dataclass

@dataclass
class ServerConfig:
    host: str
    port: int
    workers: int = 4

server = tauq.load_as('config/server.tqn', ServerConfig)

Rust

use tauq::Value;
use serde::Deserialize;

#[derive(Deserialize)]
struct Config {
    app_name: String,
    server: ServerConfig,
    features: Vec<String>,
}

#[derive(Deserialize)]
struct ServerConfig {
    host: String,
    port: u16,
    workers: u32,
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let config: Config = tauq::from_file("config/main.tqn")?;
    println!("Running {} on port {}", config.app_name, config.server.port);
    Ok(())
}

JavaScript/TypeScript

import { load } from 'tauq';

interface Config {
  app_name: string;
  server: {
    host: string;
    port: number;
    workers: number;
  };
  features: string[];
}

const config = await load<Config>('config/main.tqn');
console.log(`Starting ${config.app_name} on port ${config.server.port}`);

Best Practices

Use Comments Liberally

Document why settings exist, not just what they do. Future you will thank you.

Split by Concern

Keep database, server, and feature configs in separate files for easier management.

Use Environment-Specific Files

Create base.tqn for shared settings, then dev.tqn and prod.tqn for overrides.

Validate at Startup

Use typed loading (Rust serde, Python dataclasses) to catch config errors early.

Ready to Simplify Your Config?

Try Tauq for your next project's configuration needs.