Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Fetching contributors…
Cannot retrieve contributors at this time
156 lines (101 sloc) 3.12 KB


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.

Jump to Line
Something went wrong with that request. Please try again.