Wapp is a single-binary, statically compiled framework and interpreter for writing CLI and web applications in TCL.
This is a fork of wapp.tcl.tk. The original project is a web framework.
The goal of this fork is to create a universal tool for
both, CLI and web scripting in Tcl by adding features
that suit that goal. My changes are documented in this README.md
file.
For everything else, please refer to the original documentation:
here
–
This project is used to run ufko.org
–
Regardless of anything else, the ZipFS binary image has dependencies,
while wapptclsh
does not. Simply check tclsh
and wapptclsh
with
the ldd
program.
For the installation and running instructions, please follow these
simple steps in this wiki page:
Installation steps
Everything is built into a single, statically built (~3.7M stripped in my case) binary file:
This means it could run in various environments, including jails,
without external dependencies. The static compilation ensures
portability and simplicity in deployment.
$: ./wapptclsh
_ _ _
| | | |___ ___ ___
| | | | .'| . | . |
|_____|__,| _| _|
|_| |_|
Wapp 1.0 shell using SQLite version 3.50.0 and TCL 9.0
% Markdown::convert "# Heading1"
<h1>Heading1</h1>
% datetime "%Y-%m-%d %H:%M:%S" "'now', '+1 day'"
2025-02-21 07:06:50
% datetime "%Y-%m-%d %H:%M:%S" "'now', '+1 day', 'localtime'"
2025-02-21 08:07:13
%
$: ./wapptclsh script.tcl
Hello World!
Implement proc main in the app.tcl and ship it as a single file:
$: echo 'proc main {} { puts "All in one" }' >> app.tcl
$: make clean wapptclsh
$: ./wapptclsh
All in one
Create your first wapplication:
$: echo 'proc wapp-default {} { wapp-trim { Hello web! } }; wapp-start $argv' > index.cgi
$: ./wapptclsh index.cgi --server 8082
Listening for HTTP requests on TCP port 8082
$: curl http://localhost:8082
Hello web!
These files are optional and serve to demonstrate how to extend the
functionality of wapptclsh
. If you want to exclude these files from
the build process, please edit the Makefile
and wapptclsh.c.in
file.
functions.tcl - A collection of useful, custom functions that
extend the core capabilities of wapptclsh. These functions can simplify
common tasks and improve the usability of your projects. This file serves
as a great starting point for adding your own helper functions or utilities
to enhance the Tcl environment within Wapp.
markdown.tcl – A modified version of the Tcllib Markdown processor
with all external dependencies removed. This ensures it runs
independently within the Wapp framework. The markdown.tcl code could be
moved to functions.tcl, but since it is extensive, I decided to keep it
in a separate file. Finally, not everyone needs markdown processing,
so it makes sense.
app.tcl – A utility file for including the entire application in
the interpreter binary. After modifying app.tcl
,
you need to rebuild the binary to include the changes.
If you use Wapp for writing a CLI application, you can move all the code
that would normally be run with:
wapptclsh myscript.tcl
into app.tcl
and implement the main
function there. It will then
run automatically instead of the interactive shell.
If you use Wapp for writing a web application, you can move the code
from the main file (e.g., index.cgi
) into app.tcl
. Then,
index.cgi
can be simplified to:
#!/path/to/wapptclsh
wapp-start $argv
This way, you can ship the entire web application as
part of the interpreter binary, bringing these advantages:
wapptclsh
binary to the server.Note that I had change the compiler from gcc to cc and remove -ldl
from Makefile
because OpenBSD does not have libdl
, and since I do
not use other operating systems, I cannot test the Makefile
on
different platforms.
proc static
Added to allow you to create “static” variables that retain their values
between calls to the procedure.
See: functions.tcl : proc static
proc kv
Added as a minimalist’s key-value manager for dict-like lists. Supports
get/set/add/del/print operations.
See: functions.tcl : proc kv
proc randhex
Added to generate a random hexadecimal string using SQLite’s randomblob()
for top-notch randomness.
See: functions.tcl : proc randhex
proc test
Added as a no-nonsense test helper. Takes an expected value - either
a fixed one or a regex wrapped in //. Ditch the bloated test suites.
See: functions.tcl : proc test
proc parray
Added as a replacement for the missing parray
command and for
convenience.
See: functions.tcl : proc parray
proc datetime
Added as a replacement for the missing clock
command and for
convenience.
See: functions.tcl : proc datetime
proc wapp-set-cookie
Now supports setting an expiry time and a secure flag.
wapp-set-cookie session val
wapp-set-cookie session-secure val 0 secure
wapp-set-cookie timed val 3600
wapp-set-cookie timed-secure val 3600 secure
proc wapp-clear-cookie
wapp-clear-cookie session
wapp-clear-cookie session-secure "" -1 secure
wapp-clear-cookie timed "" -1
wapp-clear-cookie timed-secure "" -1 secure
after
append
apply
array
binary
break
catch
cd
chan
close
concat
const
continue
coroinject
coroprobe
coroutine
datetime
dict
encoding
eof
error
eval
exec
exit
expr
fblocked
fconfigure
fcopy
file
fileevent
flush
for
foreach
format
fpclassify
gets
glob
global
if
incr
info
interp
join
kv
lappend
lassign
ledit
lindex
linsert
list
llength
lmap
load
lpop
lrange
lremove
lrepeat
lreplace
lreverse
lsearch
lseq
lset
lsort
namespace
open
package
parray
pid
proc
puts
pwd
randhex
read
regexp
regsub
rename
return
scan
seek
set
socket
source
split
sqlite
sqlite3
static
string
subst
switch
tailcall
tell
test
throw
time
timerate
trace
try
unload
unset
update
uplevel
upvar
variable
vwait
wapp
wapp-allow-xorigin-params
wapp-before-dispatch-hook
wapp-before-reply-hook
wapp-cache-control
wapp-clear-cookie
wapp-content-security-policy
wapp-debug-env
wapp-mimetype
wapp-param
wapp-param-exists
wapp-param-list
wapp-redirect
wapp-reply-code
wapp-reply-extra
wapp-reset
wapp-safety-check
wapp-set-cookie
wapp-set-param
wapp-start
wapp-subst
wapp-trim
wapp-unsafe
wappInt-%HHchar
wappInt-close-channel
wappInt-decode-query-params
wappInt-decode-url
wappInt-enc
wappInt-enc-html
wappInt-enc-qp
wappInt-enc-string
wappInt-enc-unsafe
wappInt-enc-url
wappInt-gzip-reply
wappInt-handle-cgi-request
wappInt-handle-request
wappInt-handle-request-unsafe
wappInt-http-readable
wappInt-http-readable-unsafe
wappInt-new-connection
wappInt-parse-header
wappInt-scgi-readable
wappInt-scgi-readable-unsafe
wappInt-start-browser
wappInt-start-listener
wappInt-trace
wapptclsh_init
while
yield
yieldto
zipfs
zlib