Need help with imp.el?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.


Impatient html mode. See your changes in the browser as you type

128 Stars 24 Forks 113 Commits 9 Opened issues

Services available

Need anything else?

Impatient Mode

See the effect of your HTML as you type it.

Installation through MELPA

The easiest way to get up and running with impatient-mode is to install it through MELPA. If you're not already using MELPA, it's quite easy to setup.

Installation from Source

If you are installing from source, please note that this package requires both simple-httpd and htmlize in order to operate. The simple-httpd webserver runs within emacs to serve up your buffers as you edit them. htmlize is used to send font lock highlighting to clients for non-HTML buffers.

simple-httpd can be installed through MELPA or directly from GitHub.


htmlize is also available through MELPA.

Once you have installed simple-httpd and htmlize and you've cloned impatient-mode, you can add impatient-mode to your load path and require it:

(add-to-list 'load-path "~/.emacs.d/impatient-mode")
(require 'impatient-mode)

Using impatient-mode

Enable the web server provided by simple-httpd:

M-x httpd-start

Publish buffers by enabling the minor mode

M-x impatient-mode

And then point your browser to http://localhost:8080/imp/, select a buffer, and watch your changes appear as you type!

If you are editing HTML that references resources in other files (like CSS) you can enable impatient-mode on those buffers as well. This will cause your browser to live refresh the page when you edit a referenced resource.

Except for

buffers, buffer contents will be run through a user-defined filter. The default user filter is
, but you can set your own with
. The user filter is nothing but a regular elisp function. Here's how you would define a basic filter:
(defun my-filter (_)
  (princ "test" (current-buffer)))

The original editing buffer is passed along the user filter as a parameter, which we didn't use in the previous example, but which is demonstrated in the following example:

(defun my-filter (buffer)
  (let ((count 
     (with-current-buffer buffer
           (count-words-region (point-min) (point-max)))))
    (princ (format  "%d" count) (current-buffer))))

You can remove user filters with

, which will reset the default
. For reference, this is how the default user function is defined:
(defun default-user-filter (buffer)
  "Htmlization of buffers before sending to clients."
  (let ((html-buffer (save-match-data (htmlize-buffer buffer))))
    (insert-buffer-substring html-buffer)
    (kill-buffer html-buffer)))

Security implications

Please be aware that enabling

exposes the whole directory in which the file resides, not only the file itself. If our file is accessible under
, it is possible to access
. It's especially dangerous when enabling
for files like
because it allows to access any file in the user's home directory files such as

This behavior is not a bug, it is needed for the HTML files to work properly along with their resources (such as CSS and JS). Please be aware of what is exposed and/or configure your filewall accordingly.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.