What DustMote
Where https://web.archive.org/web/20020209072608/http://www.simtel.net/pub/pd/6948.html
Description A web server in one page of Tcl code.
A tiny HTTP server written in Tcl with nearly no features.
Designed for the user to easily add the features they want in Tcl.
Size is only 3k, so it can be easily modified.
Uses non-blocking channels to support many clients simultaneously.
Tested heavily on Windows 95, moderately on Linux, and lightly on MacOS.
Updated 10/2002
Contact mailto:[email protected] (Harold Melvin Kaplan)

LES on 20040929: The wind of time has taken this dust mote away. We shall be taken as well sooner or later.

Larry Smith on 20041007: It's small enough that it can be included here:


# This web server program has a smaller source than any other
# that I have seen or heard of.
# Its name is DustMote, and I hereby place it in the public domain.

# I wrote it in the Tcl language because Tcl is free, easy, stable, and
# well documented. For more documentation than comes with the Tcl
# download, one may purchase Brent B. Welch's excellent book, "Practical
# Programming in Tcl and Tk," second edition, Prentice Hall PTR. It is
# well worth the money. It is true that Tcl is not remarkably speedy, but
# it is fast enough for my site, and, though not multi-threaded, it can
# handle many clients at the same time asynchronously, by the use of
# non-blocking channels.

# Of course, there are now many freeware server programs to be downloaded
# from the web, and most of them are sturdy professional jobs that go like
# lightning and swarm with useful features. The businessperson ought to
# use one of those. I am an amateur, so I had to write the program myself.
# There are nearly no features. All DustMote can do is serve files, both
# text and image. I offer it to fellow amateurs, so they can ignore other
# people's features and think up new features that have never been thought
# up before.

# If you do use my program, remember to change the definition of "root" to
# suit your computer. Be sure to use forward slashes, not backward, or
# else double them so Tcl will understand them rightly.

# Please E-mail complaints to [email protected] and do not try to spare my
# feelings. The date of this revision is May 26, 1998.

# Yours truly,
# Harold Kaplan.

set root "f:/public_html"
set default "index.html"
set port 80

proc bgerror {trouble} {puts stdout "bgerror: $trouble"}

proc answer {socketChannel host2 port2} {
  fileevent $socketChannel readable [list readIt $socketChannel]

proc readIt {socketChannel} {
  global root default
  fconfigure $socketChannel -blocking 0
  set gotLine [gets $socketChannel]
  if { [fblocked $socketChannel] } then {return}
  fileevent $socketChannel readable ""
  set shortName "/"
  regexp {/[^ ]*} $gotLine shortName
  set many [string length $shortName]
  set last [string index $shortName [expr {$many-1}] ]
  if {$last=="/"} then {set shortName $shortName$default }
  set wholeName $root$shortName

  if {[catch {set fileChannel [open $wholeName RDONLY] } ]} {
    puts $socketChannel "HTTP/1.0 404 Not found"
    puts $socketChannel ""
    puts $socketChannel "<html><head><title><No such URL.></title></head>"
    puts $socketChannel "<body><center>"
    puts $socketChannel "The URL you requested does not exist on this site."
    puts $socketChannel "</center></body></html>"
    close $socketChannel
  } else {
    fconfigure $fileChannel -translation binary
    fconfigure $socketChannel -translation binary -buffering full
    puts $socketChannel "HTTP/1.0 200 OK"
    puts $socketChannel ""
    fcopy $fileChannel $socketChannel -command [list done $fileChannel $socketChannel]


proc done {inChan outChan args} {
  close $inChan
  close $outChan

socket -server answer $port
vwait forever


MS offers a small change that will increase the performance for multiple simultaneous queries. Key idea: replace read/puts with fcopy. Incidentally, that should be puts -nonewline in the original.

The idea is to add

    proc done {inChan outChan args} {
        close $inChan
        close $outChan

move the "close $socketChannel" to the first branch, and replace the last three lines of the second branch with

     fcopy $fileChannel $socketChannel -command [list done $fileChannel $socketChannel]

MJ - 20070128: Added suggestion by MS and braced expr's


  • outstanding 41 lines of code!
  • works with images
  • smaller than wibble
  • mini demo webserver seems not to work with images
  • smallest tcl server to run a internal info website with just tcl 8.6 and dustmote! awesome!

dbohdan 2015-04-07: Tclssg includes a modified version of DustMote . This version can log requests to stdout, serves files with MIME type (Content-Type) specified and supports custom route handlers. It is wrapped in a namespace for easier embedding and does not require Tcllib.

The following is an example of a custom handler:

::tclssg::webserver::add-handler /bye {
    socketChannel {
        puts "shutting down"
        puts $socketChannel {HTTP/1.0 204 No Content}
        puts $socketChannel {}
        close $socketChannel
        set ::tclssg::webserver::done 1

A further extended version that uses Snit can be found through a link below.

See also

DustMote derivatives

Similar Web servers