Chilkat is a commercial library of 90-plus classes for networking, cryptography and file formats — HTTP/REST, SFTP/SSH, IMAP/SMTP e-mail, RSA and other crypto, PDF, zip/tar, Amazon S3 and Azure, X.509 certificates and much more — all callable from Tcl. Think of it as the batteries Tcl didn't ship with: one commercial dependency instead of a dozen half-maintained packages, with the same API across macOS, Linux and Windows.
This page is based on a talk given at EuroTcl 2026 (Vienna) by John Buckman, who uses Chilkat in production at https://decentespresso.com
Home page and downloads: https://www.chilkatsoft.com/
Why bother?
Sometimes you need SFTP, S3, PDF, IMAP and RSA — today. Tcl's core and the usual extensions get you part of the way, but assembling a stack from unrelated packages means a sprawling dependency tree, version conflicts and platform quirks. Chilkat is one vendor, one architecture, one release cycle, well documented and actively maintained. You buy it once, unlock it, and stop reinventing protocols.
What you get in one library
Full grouped class list: https://www.chilkatsoft.com/refdoc/tcl.asp
Loading and unlocking
Chilkat is a loadable shared library. Load it once, then unlock the whole bundle once per process. Pass any string to UnlockBundle to start a free 30-day trial, or your purchased unlock code to license it permanently.
# Load the shared library (.dll / .so / .dylib); the Tcl package name is "chilkat"
load ./chilkat.dll chilkat
# Unlock once per process — every class becomes usable afterwards
set glob [new_CkGlobal]
set success [CkGlobal_UnlockBundle $glob $unlockCode]
if {[CkGlobal_get_UnlockStatus $glob] < 1} {
puts [CkGlobal_lastErrorText $glob] ;# 2 = purchased, 1 = trial, 0 = failed
}
delete_CkGlobal $glob
# ... now create any object you like
set http [new_CkHttp]In practice you put the load-and-unlock lines in one shared loader script and source it from every program.
The Tcl calling conventions
Chilkat's Tcl binding (historically generated with SWIG) maps every class method and property to a flat command. Learn these five patterns once:
The string-return rule (the most common newcomer mistake): a method whose Chilkat return type is a string has a Tcl variant starting with a lowercase letter that returns the string directly. Almost always use the lowercase form:
set body [CkHttp_quickGetStr $http $url] ;# string -> lowercase first letter set err [CkHttp_lastErrorText $http] set cn [CkCert_subjectCN $cert]
Methods returning bool/int stay PascalCase and return the value directly (1 = success):
set ok [CkSFtp_Connect $sftp $host 22] ;# 1/0
if {$ok != 1} { puts [CkSFtp_lastErrorText $sftp] }Because a returned string can't itself signal failure, check success of a string-returning call with Ck<Class>_get_LastMethodSuccess $o afterward.
You allocate, you free
There is no garbage collector behind these handles. Every new_ needs a matching delete_, including on error and early-exit paths — long-lived servers leak fast otherwise. A common idiom is to wrap an object in a proc that deletes it in a finally-style block. Binary results come back as byte strings (or via a BinData container — see below).
Error handling
Every object accumulates a diagnostic log. When anything fails, print Ck<Class>_lastErrorText $o — it explains exactly what went wrong. Detect failure two ways:
Examples
Each example below is adapted from the runnable snippets at https://www.example-code.com/tcl/ (one page per topic). They assume the library is already loaded and unlocked as above.
HTTP / REST — fetch JSON with one call — https://www.example-code.com/tcl/http_quickgetstr.asp
set http [new_CkHttp]
# GET the URL straight into a string
set json [CkHttp_quickGetStr $http $url]
if {[CkHttp_get_LastMethodSuccess $http] == 0} {
puts [CkHttp_lastErrorText $http]
}
puts $json
delete_CkHttp $httpCrypto & RSA — encrypt a string — https://www.example-code.com/tcl/rsa_encryptStrings.asp
set rsa [new_CkRsa] set privKey [new_CkPrivateKey] CkRsa_GenKey $rsa 2048 $privKey set pubKey [new_CkPublicKey] CkPrivateKey_ToPublicKey $privKey $pubKey CkRsa_put_EncodingMode $rsa "hex" CkRsa_UsePublicKey $rsa $pubKey set enc [CkRsa_encryptStringENC $rsa $plain 0]
SFTP / SSH — download a file — https://www.example-code.com/tcl/sftp_downloadFile.asp
set sftp [new_CkSFtp] CkSFtp_Connect $sftp $host 22 CkSFtp_AuthenticatePw $sftp $user $pw CkSFtp_InitializeSftp $sftp set h [CkSFtp_openFile $sftp "hamlet.xml" "readOnly" "openExisting"] CkSFtp_DownloadFile $sftp $h "hamlet.xml" delete_CkSFtp $sftp
IMAP / SMTP — send an e-mail — https://www.example-code.com/tcl/smtp_simpleSend.asp
set mailman [new_CkMailMan] CkMailMan_put_SmtpHost $mailman $host CkMailMan_put_SmtpPort $mailman 465 CkMailMan_put_SmtpSsl $mailman 1 set email [new_CkEmail] CkEmail_put_Subject $email "Hello" CkEmail_put_From $email $from CkEmail_AddTo $email "Admin" $to CkMailMan_SendEmail $mailman $email
PDF — digitally sign a document — https://www.example-code.com/tcl/sign_pdf_simple.asp
set pdf [new_CkPdf] CkPdf_LoadFile $pdf "hello.pdf" set cert [new_CkCert] CkCert_LoadPfxFile $cert "signer.pfx" "secret" CkPdf_SetSigningCert $pdf $cert set json [new_CkJsonObject] CkJsonObject_UpdateInt $json "signingTime" 1 CkPdf_SignPdf $pdf $json "hello_signed.pdf"
Zip / Tar — create an archive — https://www.example-code.com/tcl/zip_one_file.asp
set zip [new_CkZip] CkZip_NewZip $zip "test.zip" # 0 = store the file without its path CkZip_AddFile $zip "HelloWorld.txt" 0 CkZip_WriteZipAndClose $zip delete_CkZip $zip
S3 — upload a file to Amazon S3 — https://www.example-code.com/tcl/s3_uploadFile.asp
set http [new_CkHttp]
CkHttp_put_AwsAccessKey $http $accessKey
CkHttp_put_AwsSecretKey $http $secretKey
set ok [CkHttp_S3_UploadFile $http "seahorse.jpg" "image/jpeg" $bucket "seahorse.jpg"]
if {$ok != 1} { puts [CkHttp_lastErrorText $http] }
delete_CkHttp $httpCertificates — load an X.509 cert — https://www.example-code.com/tcl/cert_load_pem.asp
set cert [new_CkCert] CkCert_LoadFromFile $cert "cert.pem" puts "Subject: [CkCert_subjectCN $cert]" puts "Issuer: [CkCert_issuerCN $cert]" puts "Serial: [CkCert_serialNumber $cert]" delete_CkCert $cert
Binary data and hashing
For binary payloads use a BinData container rather than raw byte strings — it is cleaner from a scripting language and supports base64/hex encoding, file I/O and more:
set bd [new_CkBinData] CkBinData_AppendString $bd "hello world" "utf-8" set b64 [CkBinData_getEncoded $bd "base64"] ;# -> aGVsbG8gd29ybGQ= CkBinData_WriteFile $bd "/tmp/out.bin" delete_CkBinData $bd
Hashing and encoding go through Crypt2; encoding modes are strings (hex, base64, base64url, url, quoted-printable, …):
set crypt [new_CkCrypt2] CkCrypt2_put_HashAlgorithm $crypt "sha256" CkCrypt2_put_EncodingMode $crypt "hex" set digest [CkCrypt2_hashStringENC $crypt "hello world"] delete_CkCrypt2 $crypt
Reference documentation
Per-class Tcl reference pages follow a fixed URL pattern — substitute the class name:
https://www.chilkatsoft.com/refdoc/tcl<ClassName>Ref.html
For example tclHttpRef.html, tclSFtpRef.html, tclRsaRef.html, tclJsonObjectRef.html, tclCertRef.html. Index of all classes: https://www.chilkatsoft.com/refdoc/tcl.asp
Runnable Tcl examples, grouped by topic: https://www.example-code.com/tcl/default.asp
See also
Category Package — Category Internet — Category Cryptography