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+*.ymlauto-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.
config.yaml support in 10 minutesBoth 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.