Skip to content


Subversion checkout URL

You can clone with
Download ZIP
evented io webserver right inside your emacs.
Emacs Lisp Other
Tag: working_GET

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.



An attempt to make an emacs lisp clone of nodejs.

Apparently Steve Yegge has already done this... but I couldn't find it so I'm writing it.

Why elnode??

It's like "hell, no". It's... well.... it's an, um, joke.

How does it work?

Well... you can define a handler function:

(defun nicferrier-handler (httpcon)
  "Demonstration function"
  (elnode-http-start httpcon "200" '("Content-type" . "text/html"))
  (elnode-http-return httpcon "<html><b>HELLO!</b></html>")

And then start the server:

(elnode-start 'nicferrier-handler 8000)

You can also start the server interactively... you still have to pass it a handler function and a port.

Stopping the server

If you can remember the port you started your server on then you'll be able to stop it, like:

(elnode-stop 8000)

HTTP interface


You can query headers in the HTTP request in your handler using the function elnode-http-header:

(defun my-handler (httpcon)
  (elnode-http-header httpcon "Content-type")


(elnode-http-method httpcon)


(elnode-http-pathinfo httpcon)


(elnode-http-query httpcon)

query parameters

(elnode-http-params httpcon)

this returns an alist of the params in the query.


(elnode-http-version httpcon)


Handler functions can be simple functions to respond to everything coming into a server. It's more normal that you would have a server that did different things on different urls so elnode provides a url dispatcher function, you can use it like this:

  (elnode-dispatcher httpcon
                     '(("/$" . 'root-handler)
                       ("users/$" . 'users-handler))))

One of the chief advantages of any lisp is the amount of flexibility there can be in code like this. If elnode is at all successfull at catching people's imaginations I would expect a variety of dispatchers to emerge.

Calling processes

There is support for calling unix processes asynchronously and mapping the output to an HTTP connection:

(elnode-child-process httpcon 
    "cat" "/home/nferrier/elnode/example.html"

Would call the program cat with the HTML file as an argument. The output of the process will be copied to the HTTP connection asychronously (so fast).

File serving

elnode includes a file-server handler maker. This can be used to make file servers with specific docroots (so you're not tied to just one).

Here's an example usage:

(defvar docroot "~/www")
(defun my-handler (httpcon)
  (let ((webserver (elnode-webserver-handler-maker docroot)))
    (elnode-dispatcher httpcon
                       '(("/$" . webserver)
                         ("users/$" . 'users-handler)))))

One point of interest is that the webserver tools are written using the child-process tools, specifically, elnode serves files by calling unix /cat/.


There's always a but.

The HTTP parsing isn't very complete, we don't parse any data sent through POST.

The error handling is absolute rubbish. It will get better.

Something went wrong with that request. Please try again.