Critcl – C Runtime in Tcl

by ofalkaedon 8/3/2025, 7:58 PMwith 17 comments

by bb01100100on 8/3/2025, 10:05 PM

I was doing some looping recently with tcl and comparing against another implementation (called Jim [1], a very cool project in its own right) and wondered why datetime formatting was so slow when using `clock format`.

The code at [2] provided an alternative approach using C via critcl. It was interesting to see how malleable tcl can be.

[1] https://github.com/msteveb/jimtcl [2] https://wiki.tcl-lang.org/page/speed+up+clock+format+and+clo...

by NelsonMinaron 8/3/2025, 9:49 PM

Still in active development, or at least maintenance. https://github.com/andreas-kupries/critcl/commits/master/

by monetuson 8/3/2025, 11:48 PM

I've been using critcl for a long time, and maybe weirdly still end up using it despite often using nim. Fantastic software.

by qalmakkaon 8/6/2025, 4:11 PM

This is insane and I love it. Just like Tcl. The fact everything is a string in Tcl makes embedding languages wonderfully simple.

by johnisgoodon 8/6/2025, 5:52 PM

Somewhat related, it is something I have been trying to figure out, and I did, successfully! This information might help others.

You can create a standalone binary from .tcl files by using KitCreator and sdx (Starkit Developer eXtension). You need to wrap your Tcl script into a .kit file (a virtual filesystem), then combine it with a Tcl runtime to produce a native ELF (or Windows) binary. Optionally, you can encrypt your Tcl code with AES (e.g., using openssl enc) before embedding it, and decrypt it at runtime via a custom loader. The result is a self-contained executable that runs anywhere Tcl is supported. :)

I have a script for it!

  Standalone encrypted application created:
  -> /tmp/tcl/app.run
  -> AES KEY (hex): 95a8a95e8322344b808ebd3fd3986b5b
  -> AES IV  (hex): 69eac67341d2657a0b00d3006addb131
  -> To run it: ./app.run

  $ ./app.run
  Hello world from binary!
  $ file app.run
  app.run: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=f3fabb748cc7e61c2fafc7c288f282db2f6de0c7, for GNU/Linux 3.2.0, stripped
The generated app.run is 10 MB and ldd shows it only needs "linux-vdso", "libm", "libc", and "ld-linux-*".

Useful links (taken from my script):

  TCL_VERSION="9.0.1"
  TCL_SRC_URL="https://sourceforge.net/projects/tcl/files/Tcl/${TCL_VERSION}/tcl${TCL_VERSION}-src.tar.gz"
  SDX_KIT_URL="https://chiselapp.com/user/aspect/repository/sdx/uv/sdx-20110317.kit"
  TCLLIB_URL="https://github.com/tcltk/tcllib/archive/refs/heads/main.zip"
I wonder if there is a more recent sdx, although it still works.

FWIW, the steps are:

  1. Download and build Tcl
  2. Clone KitCreator and build Tclkit
  3. Download SDX
  4. Create the loader ($VFS_DIR/main.tcl)
  5. Download and extract Tcllib (optional)
  6. Copy any modules you want from Tcllib (optional)
  7. Add dummy assets to $VFS_DIR/assets/data.json (has a specific format) (probably optional)
  8. Wrap and generate .kit and final .run ELF (you need 2 Tclkit binaries, just duplicate it)
If you have any questions, let me know!

---

I have used critcl before, but can't find my code anymore. :( It is good stuff though.

by forintion 8/3/2025, 9:38 PM

I suppose you would use this to do low level stuff because it's much harder to do in TCL, but it just doesn't feel right.

It makes more sense to me to embed Tk into a C program.

by hoherdon 8/4/2025, 1:52 AM

Not to be confused with the kubernetes container runtime interface CLI https://github.com/kubernetes-sigs/cri-tools/blob/master/doc...