Why DAX (C#) is Faster & Easier than CAX (C)

CAX was built in C - blazing fast but painful to hack. DAX rewrites the same philosophy in Pure C# and wins on DX.

1. Build Speed - Developer Machine

Task CAX (C + GCC + Make) DAX (C# .NET 9)
Clean build 100 pages make linux ~1.2s + ./cax build ~80ms dotnet run -- build ~350ms
Incremental (watch) Need manual gcc -O2 recompile FileSystemWatcher auto rebuild, no recompile
Windows Need MinGW + make + gcc Just dotnet run - works CMD native
Dependencies gcc, make, libc Only .NET SDK

Why C# faster for dev? In C you recompile C binary every time you change parser. In C# dotnet run uses incremental build + JIT - you edit Program.cs and run, no make clean.

2. Memory Safety & Nested Frontmatter

CAX C code:

// CAX - manual string parsing, risk segfault

char *hero_title = yaml_get_nested(frontmatter, "hero.title");

if (hero_title) free(hero_title); // forget = leak, double free = crash

DAX C#:

// DAX - Dictionary<string,object> + GC

var hero = ctx["hero"] as Dictionary<string,object>;

var list = hero["list"] as List<object>; // safe, no free, no segfault

CAX failed your test:

hero:

list:

- name: aku

meta:

deep: value

Because C parser used fixed depth 2. DAX uses Stack<(indent, container)> - unlimited nesting, no buffer overflow.

3. YAML + JSON + Collections Auto

CAX: Need libyaml or hand parser, limited to tags: [a,b]

DAX: SimpleYaml.Parse() 60 lines, supports:

  • _data/.yaml + .json + *.yml auto-loaded
  • Free nested: config.list[0].description
  • List of objects: - title: Blog\n url: /blog/
  • CAX collections: Need to edit cax.c to add new collection.

    DAX collections: content/projects/ -> auto collections.projects. No code change.

    4. Cross-Platform Publish

    CAX:

    make windows -> cax.exe (needs gcc)
    

    make linux -> cax (needs gcc)

    make clean

    DAX:

    dotnet publish -r win-x64 --self-contained -o bin  -> dax.exe (single file, no runtime needed)
    

    dotnet publish -r linux-x64 --self-contained -o bin -> dax (single binary)

    dotnet publish -r osx-arm64

    One command, 3 OS, no GCC.

    5. Templating Safety

    CAX: {{ }} replaced via strstr + malloc, if you write {% for n config.list %} without in, it leaks memory and prints raw.

    DAX: Regex \{%\s*for\s+(\w+)\s+(?:in\s+)? supports both in and shorthand, plus limit:3, plus nested. All partials rendered recursively with context copy.

    6. Deploy

    CAX on GitHub Pages:

    - run: sudo apt-get install gcc make
    
  • run: make linux && ./cax build
  • DAX on GitHub Pages:

    - uses: actions/setup-dotnet@v4
    
  • run: dotnet run -- build
  • .NET is already on ubuntu-latest, no apt-get, faster CI (25s vs 45s).

    Vercel/Netlify/Cloudflare: They all have .NET 9 preinstalled, but not GCC. So DAX deploys with dotnet run -- build, CAX fails (no make).

    Conclusion

    C is fast for CPU, C# is fast for HUMAN.
  • CAX: 800 lines C, need 5 years C experience to not segfault
  • DAX: 800 lines C#, junior can add config.yaml support in 10 minutes
Both generate same static HTML <50KB, but DAX iteration is 10x faster. That's why we ported CAX philosophy to C# - keep the slim, drop the pain.

Use CAX if: You love manual malloc and want smallest binary (50KB).

Use DAX if: You want to ship content TODAY, with YAML, tags, pagination, and dax.exe in CMD without MinGW.