Under Active Development

The Swiss Army Knife
of Data Formats

Config, Code, and Crypto in One .mdix File

A programmable configuration format that lets you factor repetition into functions. Define patterns once, reuse them everywhere — with built-in encryption and compression, zero dependencies.

Submit packages to the registry and manage credentials at mms-accounts.pages.dev — your MidManStudio identity hub.
68%+
Size reduction on real-world configs
One File
Config + logic + encryption
Zero Deps
Pure Rust core with FFI bindings

"I built this because I was tired of copy-pasting the same JSON config blocks 500 times. Turns out other people hate that too."

— Mid-D-Man, Creator

See It In Action

5 microservices in JSON vs DixScript. DB host, Redis URL, healthcheck defaults and log level are all derived from one function — change one line, all five services update.

config.json
{
  "environment": "production",
  "services": [
    {
      "name": "auth-service",
      "image": "auth-service:v1.2.3",
      "port": 8080,
      "replicas": 3,
      "resources": { "cpu": "500m", "memory": "512Mi" },
      "env": {
        "DB_HOST": "postgres.auth.prod.internal",
        "DB_PORT": "5432",
        "DB_USER": "app",
        "REDIS_URL": "redis://auth-cache.prod.internal:6379",
        "LOG_LEVEL": "INFO",
        "ENV": "production"
      },
      "secrets": ["DB_PASSWORD", "JWT_SECRET"],
      "healthcheck": { "path": "/health", "interval": "30s", "timeout": "3s" }
    },
    {
      "name": "payment-service",
      "image": "payment-service:v2.1.0",
      "port": 8081,
      "replicas": 2,
      "resources": { "cpu": "750m", "memory": "1Gi" },
      "env": {
        "DB_HOST": "postgres.payment.prod.internal",
        "DB_PORT": "5432",
        "DB_USER": "app",
        "REDIS_URL": "redis://payment-cache.prod.internal:6379",
        "LOG_LEVEL": "INFO",
        "ENV": "production",
        "STRIPE_URL": "https://api.stripe.com"
      },
      "secrets": ["DB_PASSWORD", "STRIPE_SECRET"],
      "healthcheck": { "path": "/health", "interval": "30s", "timeout": "3s" }
    },
    {
      "name": "user-service",
      "image": "user-service:v3.0.1",
      "port": 8082,
      "replicas": 4,
      "resources": { "cpu": "400m", "memory": "384Mi" },
      "env": {
        "DB_HOST": "postgres.users.prod.internal",
        "DB_PORT": "5432",
        "DB_USER": "app",
        "REDIS_URL": "redis://user-cache.prod.internal:6379",
        "LOG_LEVEL": "INFO",
        "ENV": "production"
      },
      "secrets": ["DB_PASSWORD"],
      "healthcheck": { "path": "/health", "interval": "30s", "timeout": "3s" }
    },
    {
      "name": "orders-service",
      "image": "orders-service:v1.4.0",
      "port": 8083,
      "replicas": 3,
      "resources": { "cpu": "600m", "memory": "768Mi" },
      "env": {
        "DB_HOST": "postgres.orders.prod.internal",
        "DB_PORT": "5432",
        "DB_USER": "app",
        "REDIS_URL": "redis://orders-cache.prod.internal:6379",
        "LOG_LEVEL": "INFO",
        "ENV": "production"
      },
      "secrets": ["DB_PASSWORD"],
      "healthcheck": { "path": "/health", "interval": "30s", "timeout": "3s" }
    },
    {
      "name": "notifications-service",
      "image": "notifications-service:v0.9.5",
      "port": 8084,
      "replicas": 2,
      "resources": { "cpu": "300m", "memory": "256Mi" },
      "env": {
        "DB_HOST": "postgres.notifications.prod.internal",
        "DB_PORT": "5432",
        "DB_USER": "app",
        "REDIS_URL": "redis://notifications-cache.prod.internal:6379",
        "LOG_LEVEL": "INFO",
        "ENV": "production",
        "SMTP_HOST": "smtp.prod.internal",
        "SMTP_PORT": "587"
      },
      "secrets": ["DB_PASSWORD", "SMTP_PASSWORD"],
      "healthcheck": { "path": "/health", "interval": "30s", "timeout": "3s" }
    }
  ],
  "feature_flags": {
    "checkout_v2": false,
    "recommendations": true,
    "beta_banner": false
  },
  "logging": {
    "default_level": "INFO",
    "json_output": true
  }
}
config.mdix
@CONFIG(
  version     -> "1.0.0"
  description -> "Multi-service production config"
)

@ENUMS(
  Environment { DEV, STAGING, PROD }
)

@QUICKFUNCS(
  ~dbHost(svcName, env) {
    suffix = env == Environment.PROD    ? "prod.internal"
           : env == Environment.STAGING ? "staging.internal"
           : "dev.internal"
    return $"postgres.{svcName}.{suffix}"
  }

  ~redisUrl(svcName, env) {
    suffix = env == Environment.PROD    ? "prod.internal"
           : env == Environment.STAGING ? "staging.internal"
           : "dev.internal"
    return $"redis://{svcName}-cache.{suffix}:6379"
  }

  ~service(name, image, port, replicas, cpu, memory, env) {
    return {
      name      = name
      image     = image
      port      = port
      replicas  = replicas
      resources = { cpu = cpu, memory = memory }
      env = {
        DB_HOST   = dbHost(name, env)
        DB_PORT   = "5432"
        DB_USER   = "app"
        REDIS_URL = redisUrl(name, env)
        LOG_LEVEL = "INFO"
        ENV       = "production"
      }
      healthcheck = { path = "/health", interval = "30s", timeout = "3s" }
    }
  }
)

@DATA(
  environment = Environment.PROD

  logging:
    default_level = "INFO"
    json_output   = true

  feature_flags:
    checkout_v2     = false
    recommendations = true
    beta_banner     = false

  services::
    service("auth-service",          "auth-service:v1.2.3",          8080, 3, "500m", "512Mi", environment),
    service("payment-service",       "payment-service:v2.1.0",       8081, 2, "750m", "1Gi",   environment),
    service("user-service",          "user-service:v3.0.1",          8082, 4, "400m", "384Mi", environment),
    service("orders-service",        "orders-service:v1.4.0",        8083, 3, "600m", "768Mi", environment),
    service("notifications-service", "notifications-service:v0.9.5", 8084, 2, "300m", "256Mi", environment)
)
0% Smaller DixScript saves 0 bytes across 5 services. Scale to 50 services and the gap grows linearly.
Real-World Comparison · RPG Weapon Database · 11 Items

JSON vs DixScript

Same data. Same output. 11 weapons, 15 fields each, 22 hardcoded prices — or one function with a formula.

220+
JSON lines
~45
DixScript lines
22
hardcoded prices in JSON
1
formula in DixScript
weapon_db.json
{
  "weapons": [
    {
      "id": "IRON_SWORD",       "name": "Iron Sword",
      "type": "SWORD",          "rarity": "COMMON",
      "damageType": "PHYSICAL",
      "baseDamage": 25,         "critChance": 0.05,
      "attackSpeed": 1.2,       "durability": 100,
      "weight": 3.5,            "requiredLevel": 1,
      "sellPrice": 50,          "buyPrice": 200,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "STEEL_SWORD",      "name": "Steel Sword",
      "type": "SWORD",          "rarity": "UNCOMMON",
      "damageType": "PHYSICAL",
      "baseDamage": 45,         "critChance": 0.08,
      "attackSpeed": 1.3,       "durability": 150,
      "weight": 4.0,            "requiredLevel": 10,
      "sellPrice": 90,          "buyPrice": 360,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "ELVEN_BLADE",      "name": "Elven Blade",
      "type": "SWORD",          "rarity": "RARE",
      "damageType": "ARCANE",
      "baseDamage": 80,         "critChance": 0.15,
      "attackSpeed": 1.6,       "durability": 120,
      "weight": 2.8,            "requiredLevel": 25,
      "sellPrice": 160,         "buyPrice": 640,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "SHADOWFANG",       "name": "Shadowfang",
      "type": "SWORD",          "rarity": "EPIC",
      "damageType": "POISON",
      "baseDamage": 120,        "critChance": 0.22,
      "attackSpeed": 1.8,       "durability": 200,
      "weight": 3.2,            "requiredLevel": 40,
      "sellPrice": 240,         "buyPrice": 960,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "EXCALIBUR",        "name": "Excalibur",
      "type": "SWORD",          "rarity": "LEGENDARY",
      "damageType": "LIGHTNING",
      "baseDamage": 200,        "critChance": 0.35,
      "attackSpeed": 2.0,       "durability": 999,
      "weight": 4.5,            "requiredLevel": 60,
      "sellPrice": 400,         "buyPrice": 1600,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "HUNTING_BOW",      "name": "Hunting Bow",
      "type": "BOW",            "rarity": "COMMON",
      "damageType": "PHYSICAL",
      "baseDamage": 20,         "critChance": 0.12,
      "attackSpeed": 0.8,       "durability": 80,
      "weight": 1.5,            "requiredLevel": 1,
      "sellPrice": 40,          "buyPrice": 160,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "YEW_BOW",          "name": "Yew Bow",
      "type": "BOW",            "rarity": "UNCOMMON",
      "damageType": "PHYSICAL",
      "baseDamage": 38,         "critChance": 0.18,
      "attackSpeed": 0.9,       "durability": 110,
      "weight": 1.8,            "requiredLevel": 12,
      "sellPrice": 76,          "buyPrice": 304,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "STORM_BOW",        "name": "Storm Bow",
      "type": "BOW",            "rarity": "RARE",
      "damageType": "LIGHTNING",
      "baseDamage": 70,         "critChance": 0.25,
      "attackSpeed": 1.1,       "durability": 140,
      "weight": 2.0,            "requiredLevel": 28,
      "sellPrice": 140,         "buyPrice": 560,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "OAK_STAFF",        "name": "Oak Staff",
      "type": "STAFF",          "rarity": "COMMON",
      "damageType": "ARCANE",
      "baseDamage": 18,         "critChance": 0.08,
      "attackSpeed": 0.7,       "durability": 90,
      "weight": 2.0,            "requiredLevel": 1,
      "sellPrice": 36,          "buyPrice": 144,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "CRYSTAL_STAFF",    "name": "Crystal Staff",
      "type": "STAFF",          "rarity": "RARE",
      "damageType": "ICE",
      "baseDamage": 65,         "critChance": 0.18,
      "attackSpeed": 0.9,       "durability": 130,
      "weight": 2.5,            "requiredLevel": 22,
      "sellPrice": 130,         "buyPrice": 520,
      "stackable": false,       "isQuestItem": false
    },
    {
      "id": "ARCANE_SCEPTER",   "name": "Arcane Scepter",
      "type": "STAFF",          "rarity": "EPIC",
      "damageType": "ARCANE",
      "baseDamage": 110,        "critChance": 0.28,
      "attackSpeed": 1.0,       "durability": 180,
      "weight": 2.2,            "requiredLevel": 45,
      "sellPrice": 220,         "buyPrice": 880,
      "stackable": false,       "isQuestItem": false
    }
  ]
}
weapon_db.mdix
@ENUMS(
  WeaponType { SWORD, BOW, STAFF, DAGGER, AXE }
  Rarity     { COMMON = 0, UNCOMMON = 1, RARE = 2, EPIC = 3, LEGENDARY = 4 }
  DamageType { PHYSICAL, FIRE, ICE, LIGHTNING, POISON, ARCANE }
)

@QUICKFUNCS(
  ~weapon(id, name, type, rarity, dmgType, damage, crit, speed, durability, weight, level) {
    return {
      Id = id,  Name = name
      WeaponType = type,  Rarity = rarity,  DamageType = dmgType
      BaseDamage = damage,  CritChance = crit,  AttackSpeed = speed
      Durability = durability,  Weight = weight,  RequiredLevel = level
      SellPrice = damage * 2
      BuyPrice  = damage * 8
      Stackable = false,  IsQuestItem = false
    }
  }
)

@DATA(
  weapons::
    weapon("IRON_SWORD",    "Iron Sword",    WeaponType.SWORD, Rarity.COMMON,    DamageType.PHYSICAL,   25, 0.05, 1.2, 100, 3.5,  1),
    weapon("STEEL_SWORD",   "Steel Sword",   WeaponType.SWORD, Rarity.UNCOMMON,  DamageType.PHYSICAL,   45, 0.08, 1.3, 150, 4.0, 10),
    weapon("ELVEN_BLADE",   "Elven Blade",   WeaponType.SWORD, Rarity.RARE,      DamageType.ARCANE,     80, 0.15, 1.6, 120, 2.8, 25),
    weapon("SHADOWFANG",    "Shadowfang",    WeaponType.SWORD, Rarity.EPIC,      DamageType.POISON,    120, 0.22, 1.8, 200, 3.2, 40),
    weapon("EXCALIBUR",     "Excalibur",     WeaponType.SWORD, Rarity.LEGENDARY, DamageType.LIGHTNING, 200, 0.35, 2.0, 999, 4.5, 60),
    weapon("HUNTING_BOW",   "Hunting Bow",   WeaponType.BOW,   Rarity.COMMON,    DamageType.PHYSICAL,   20, 0.12, 0.8,  80, 1.5,  1),
    weapon("YEW_BOW",       "Yew Bow",       WeaponType.BOW,   Rarity.UNCOMMON,  DamageType.PHYSICAL,   38, 0.18, 0.9, 110, 1.8, 12),
    weapon("STORM_BOW",     "Storm Bow",     WeaponType.BOW,   Rarity.RARE,      DamageType.LIGHTNING,  70, 0.25, 1.1, 140, 2.0, 28),
    weapon("OAK_STAFF",     "Oak Staff",     WeaponType.STAFF, Rarity.COMMON,    DamageType.ARCANE,     18, 0.08, 0.7,  90, 2.0,  1),
    weapon("CRYSTAL_STAFF", "Crystal Staff", WeaponType.STAFF, Rarity.RARE,      DamageType.ICE,        65, 0.18, 0.9, 130, 2.5, 22),
    weapon("ARCANE_SCEPTER","Arcane Scepter",WeaponType.STAFF, Rarity.EPIC,      DamageType.ARCANE,    110, 0.28, 1.0, 180, 2.2, 45)
)
The killer advantage
SellPrice = damage * 2
BuyPrice  = damage * 8
Change the pricing formula once and all 11 weapons update instantly. In JSON you'd hunt down and recalculate 22 hardcoded numbers by hand. Add a new field like isTwoHanded? One line in the template — not 11 edits.

JSON pain points

Every weapon repeats all 15 fields — no templates, no abstraction.
"stackable": false appears 11 times — change the default? Edit 11 places.
Prices are hardcoded — typo 160 instead of 600 and the economy breaks silently.
Type values are raw strings: "SWORD", "sWoRd", "sword" all valid — zero enforcement.
220+ lines for 11 weapons. 500 weapons? Nearly 10,000 lines of identical JSON.

DixScript wins

Shape defined once in ~weapon() — adding a field means one line change, everywhere.
Stackable = false lives in the template — one truth, zero drift.
Pricing is a formula: BuyPrice = damage * 8 — transparent and auditable.
Enums enforce valid values at compile time — WeaponType.SORD is a compile error.
500 weapons? ~520 lines total. Scales linearly, not quadratically.
0% Smaller Same data, same output. The pricing formula means you never touch individual entries again.

Powerful Features Built-In

The more repetitive your configs, the more you gain by factoring patterns into QuickFuncs.

Deduplication Engine

User-defined QuickFuncs compress repetitive data at compile time. Define a structure once, reuse it everywhere. Game configs: 68%+ smaller. More repetition means more savings.

~makeItem(id, name, type, rarity, value)

QuickFuncs: Programmable Config

Write small functions that run at compile time, not at runtime. Compute derived values, enforce structure, and fan out repeated patterns without adding another scripting layer.

~service(name, image, port, replicas)

Two-Tier Data Model

Flat properties for simple settings, table and group syntax for structured data. Keep small configs minimal while still modelling complex schemas when you need them.

properties: → groups:: → arrays::

Built-in Encryption & Compression

Use DLM modules to chain compression and encryption in the same file. Ship encrypted secrets, compressed datasets, or both — without extra build tooling.

@DLM(DCompressor.gzip, DEncryptor.aes256)

Enums & Types When You Want Them

Add enums and explicit types where strictness matters, keep everything inferred when it doesn't. Readable configs that still catch mistakes before they hit production.

Environment { DEV, STAGING, PROD }

Zero-Dependency Core

A pure Rust core with FFI bindings for C#, Go, Java, Python, and WebAssembly. Use the same .mdix file across services and languages without pulling in a heavyweight runtime.

Rust · C# · Go · Java · Python · WASM

Why DixScript?

If changing one field means editing it in more than three places today, DixScript helps you pull that pattern into one reusable definition.

  • Multi-environment configs that mostly differ by URLs, credentials, and flags
  • API services sharing the same retry, timeout, and logging policies
  • Feature flags and experiment configs duplicated across clients and backends
  • Secrets stored separately from the config that actually uses them

Perfect For

Configs that have grown beyond simple key-value files but don't deserve a full application just to keep them maintainable.

Under Active Development

DixScript is not yet production-ready. The Rust port targets performance and portability, while the original C# implementation serves as the current reference.