Emacs is (obviously) perfectly capable of running a HTTP server, and someone (obviously) wrote a package for it - named, appropriately, web-server . Since it's available on ELPA (the default Emacs package repository), it was a good choice to base the implementation on.

The following is the code for basic implementation of the utility, ready to be copied into your config. Further on, I discuss it in more details, and follow up with aesthetic improvements and eshell integration. The complete code with all the improvements can be assembled from pieces posted here, or taken from this gist.

(Note that the code depends on web-server - ensure it's installed and loaded before evaluating this source block. Myself, I just put it in the :config section of use-package invocation.)

"Is the file server running? Holds an instance if so." defvar my/file-server nil defalias 'my/send-directory-list 'ws-send-directory-list ( handlers port &optional log-buffer &rest network-args ) "Like `ws-start', but unbroken for Emacs 25+." let ( server ( make-instance 'ws-server :handlers handlers :port port ) ) log get-buffer-create log-buffer when log-buffer ( process server ) :name "ws-server" :service ( port server ) :filter 'ws-filter :server t :nowait nil :family 'ipv4 :coding 'no-conversion :plist append list :server server server when log list :log-buffer log :log when log lambda proc request message let process-contact request plist-get ( process-plist proc ) :log-buffer buf goto-char point-max insert format "%s \t %s \t %s \t %s" format-time-string ws-log-time-format ( first c ) ( second c ) message with-current-buffer buf apply #'make-network-process'ws-filter'ipv4'no-conversionnetwork-args setf push server ws-servers server defun my/ws-start ( directory port ) interactive "DDirectory:

nPort: " message "File server is already running!" progn ( ( docroot directory ) ) lambda ( request ) with-slots ( process headers ) request let* path substring cdr assoc :GET headers headers ws-in-directory-p docroot path expanded if file-exists-p expanded and expanded if file-directory-p expanded ( my/send-directory-list process expanded ) expand-file-name path docroot ws-send-file process ( ws-send-404 process ) request :host "0.0.0.0" my/ws-startport nil lexical-let setf my/file-server message "Serving directory %s on port %d" directory port directory port if my/file-server defun my/serve-directory ( ) "Stop the file server if running." interactive progn ( ws-stop my/file-server ) setf my/file-server nil message "Stopped the file server." message "No file server is running." if my/file-server defun my/stop-server

Evaluating the above code is enough to get the basic functionality, as presented below: