333

Python's http.server (or SimpleHTTPServer for Python 2) is a great way of serve the contents of the current directory from the command line:

python -m http.server

However, as far as web servers go, it's very slooooow...

It behaves as though it's single threaded, and occasionally causes timeout errors when loading JavaScript AMD modules using RequireJS. It can take five to ten seconds to load a simple page with no images.

What's a faster alternative that is just as convenient?

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 18
    This thread just restored my sanity. I had been using SimpleHTTPServer and getting random errors with RequireJS that were driving me nuts! node's http-server is working like a charm. Thanks! – Dave Cadwallader Nov 15 '12 at 21:41
  • 1
    I've had the same. The Python Simple Server can be so slow that RequireJS times out. Node's is way faster, mostly I think because it can handle requests in parallel. – Drew Noakes Nov 15 '12 at 21:42
  • For portable HTTP servers in windows, take a look at http://stackoverflow.com/q/595466/198348 – Ehtesh Choudhury Jul 24 '13 at 18:22
  • 4
    @ChrisF, I have edited the question according to [this guideline](http://meta.stackoverflow.com/q/254393/24874) to more grammatically reflect the fact that this _is_ actually an answerable question. I have explained the problem I faced (namely, timeouts and wasted time), and I couldn't list what I had done to address the problem because I didn't know of any alternatives. I don't think this question fits the "What's your favourite ___" shape, as the criteria are clearly defined. Different visitors may find different answers more useful, and answers may not suit the criteria given. – Drew Noakes Aug 04 '14 at 19:53
  • 27
    Love how SO has a habit of closing people's favourite questions… – isomorphismes Oct 24 '14 at 19:26
  • 4
    This question is not only useful, it also does not match the description for which it is being closed. At least the research has already been done... – Bryan Larson Oct 28 '14 at 18:12
  • 3
    Another option, if you want to serve up a git repo, is [`git instaweb`](http://git-scm.com/docs/git-instaweb). – Drew Noakes Jan 21 '15 at 15:31
  • I came here, then I realised that as I'm developing in ReactJS I don't actually need a local server to code – Toni Leigh Oct 25 '15 at 09:07
  • Voting to close as tool rec. – Ciro Santilli OurBigBook.com Jun 04 '16 at 22:01
  • 3
    @CiroSantilli巴拿馬文件六四事件法轮功, this question has already been closed and reopened... – Drew Noakes Jun 05 '16 at 16:28

15 Answers15

422

http-server for node.js is very convenient, and is a lot faster than Python's SimpleHTTPServer. This is primarily because it uses asynchronous IO for concurrent handling of requests, instead of serialising requests.

Installation

Install node.js if you haven't already. Then use the node package manager (npm) to install the package, using the -g option to install globally. If you're on Windows you'll need a prompt with administrator permissions, and on Linux/OSX you'll want to sudo the command:

npm install http-server -g

This will download any required dependencies and install http-server.

Use

Now, from any directory, you can type:

http-server [path] [options]

Path is optional, defaulting to ./public if it exists, otherwise ./.

Options are [defaults]:

  • -p The port number to listen on [8080]
  • -a The host address to bind to [localhost]
  • -i Display directory index pages [True]
  • -s or --silent Silent mode won't log to the console
  • -h or --help Displays help message and exits

So to serve the current directory on port 8000, type:

http-server -p 8000
Community
  • 1
  • 1
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • 12
    This is awesome!! Thank you for pointing it out. It's great for testing streaming audio/video which is something the python server doesn't seem to handle well at all. – gman Nov 28 '12 at 15:44
  • @gman, I had a similar experience when I discovered it. I haven't used the Python server since. – Drew Noakes Nov 28 '12 at 16:47
  • Is there any option to have the server log output, to see if a file is not found e.g. 404 ? – poseid Mar 16 '13 at 16:59
  • @poseid, I'm not sure. Perhaps open an issue on the project itself, or fork it and add logging. – Drew Noakes Mar 16 '13 at 17:57
  • This is great for testing sites on iOS that load large numbers of files. SimpleHTTPServer was not fast enough and caused timeout on Safari. Thanks! – Rich Apodaca May 09 '13 at 02:06
  • Couldn't get this to work. Installed it and then when I ran the command 'http-server' it returned with '-bash: http-server: command not found'. – Nass Dec 26 '13 at 22:10
  • 1
    @Salmonface, did you definitely use the `-g` option, and did you make sure that no errors were printed during the installation? That error just means it cannot be found after the install, which seems unlikely if things went well. What platform are you on? Run a find command across your drive to find a file with name `http-server`. I've used this successfully on a few different Linux distros and Windows versions. – Drew Noakes Dec 27 '13 at 14:53
  • @DrewNoakes, there didn't seem to be any errors. I'm running OSX v10.9.1. What's strange is that I can find it and uninstall it with npm... – Nass Dec 29 '13 at 01:09
  • @Phy6, I rolled back your edit because the problem you are seeing in Windows means it was not installed correctly. I have used this on Windows many times. Are you sure you're typing `http-server` and not `node http-server`? The former is correct. Can't test as I'm on Linux now. – Drew Noakes Jan 07 '14 at 20:54
  • When I access some html file through this server, the browser tries to download it (!?).. curl reports the content-type as "application/octet-stream; charset=utf-8" ... how to make it work? – davidhq Feb 12 '15 at 20:56
  • @DavidKrmpotic, I haven't seen that behaviour before. Are your HTML files truly UTF-8, or are there some stray bytes in there. I don't know whether `http-server` inspects the contents to determine MIME type. I would suspect it just goes off the file extension. What extension are you using? Probably worth opening an issue on [the http-server project](https://github.com/nodeapps/http-server). [This](https://github.com/nodeapps/http-server/issues/35) may be relevant. – Drew Noakes Feb 12 '15 at 21:00
  • Actually I think I made a mistake... tried to read something.haml instead of .html.. :) Now it works! – davidhq Feb 12 '15 at 21:08
  • 2
    I just want to confirm that using this solution improved my page load time from 20s to 2s! – 0leg Dec 10 '15 at 10:57
  • 1
    Well, at first it was an improvement over the python SimpleHTTPServer until I ran out of memory. http-server consumes a huge amount of memory for large files. The myserver.go proposal is fast an consumes just about 2 MB instead of 5 GB Memory, before starting to swap and getting really slow. – daniel Apr 14 '16 at 21:03
  • Even simpler than all of the above consider [devd](https://github.com/cortesi/devd) – gman May 12 '16 at 06:47
  • Does this not support serving on both IPv4 and IPv6? – James Johnston May 19 '16 at 06:00
  • Why is this faster than Python's? – Ciro Santilli OurBigBook.com Jun 04 '16 at 22:02
  • 1
    @CiroSantilli巴拿馬文件六四事件法轮功, good question. I'll update the answer. – Drew Noakes Jun 05 '16 at 16:26
  • 1
    I had issues serving media files with this after a little bit of time running the server. – PabloRosales Jul 23 '16 at 19:15
  • 2
    So as of Nov 2019 it looks as though http-server has been broken for windows users for several months. Many of its dependencies are way out of date. One of them, ecstatic, is now abandoned so it's not clear when or if it will be fixed. I looked into fixing myself but it's also not clear if the devs will take PRs. So, I wrote my own [replacement](https://github.com/greggman/servez-cli). – gman Nov 04 '19 at 09:26
  • Use webfs instead. – Federico Nov 07 '19 at 15:06
117

I recommend: Twisted (http://twistedmatrix.com)

an event-driven networking engine written in Python and licensed under the open source MIT license.

It's cross-platform and was preinstalled on OS X 10.5 to 10.12. Amongst other things you can start up a simple web server in the current directory with:

twistd -no web --path=.

Details

Explanation of Options (see twistd --help for more):

-n, --nodaemon       don't daemonize, don't use default umask of 0077
-o, --no_save        do not save state on shutdown

"web" is a Command that runs a simple web server on top of the Twisted async engine. It also accepts command line options (after the "web" command - see twistd web --help for more):

  --path=             <path> is either a specific file or a directory to be
                      set as the root of the web server. Use this if you
                      have a directory full of HTML, cgi, php3, epy, or rpy
                      files or any other files that you want to be served up
                      raw.

There are also a bunch of other commands such as:

conch            A Conch SSH service.
dns              A domain name server.
ftp              An FTP server.
inetd            An inetd(8) replacement.
mail             An email service
... etc

Installation

Ubuntu

sudo apt-get install python-twisted-web (or python-twisted for the full engine)

Mac OS-X (comes preinstalled on 10.5 - 10.12, or is available in MacPorts and through Pip)

sudo port install py-twisted

Windows

installer available for download at http://twistedmatrix.com/

HTTPS

Twisted can also utilise security certificates to encrypt the connection. Use this with your existing --path and --port (for plain HTTP) options.

twistd -no web -c cert.pem -k privkey.pem --https=4433
Peter Gibson
  • 19,086
  • 7
  • 60
  • 64
  • 6
    Unless you already have node.js set up, I found this to be the most convenient. Thanks for sharing! – Chris J Mar 21 '13 at 09:55
  • 4
    On Ubuntu, you have to `sudo apt-get install python-twisted-web` first. (Thanks for this answer, it's very convenient!) – nkorth Jul 25 '13 at 15:55
  • 2
    One special advantage of twisted one line server, it support resumable downloads (byte range support), and that is a must have feature when you are downloading large files. – Pankaj Nov 10 '13 at 06:38
  • 8
    using node did not stream video/audio properly for me, using twistd works great though! – dizy Nov 19 '13 at 04:41
  • 2
    You can configure ports and get other options using `twistd --help` and `twistd web --help`. Took me a while to figure that out. – Ehtesh Choudhury Dec 03 '13 at 20:02
  • I honestly can't figure this out. I've installed Python 2.7. I installed twisted. The UI was kind of screwy (for both, with like, words flying off the dialogs and stuff, go figure, python can't handle 125% DPI... but where was I?) -- right -- the dialog was screwy, I think it was asking me where python was installed, in a strange way. I told it. and ... was able to proceed. I seriously have no idea where this thing installed itself. There is no file matching the pattern `*twistd*.*` anywhere on any of my hard drives after installing twisted. Very disappointed. – BrainSlugs83 Apr 04 '14 at 13:53
  • @BrainSlugs83 I would suggest asking a new question rather than posting a comment. More likely to get an answer that way – Peter Gibson Apr 04 '14 at 20:53
  • 1
    I like this because I can expect it to work out of the box on any Mac. It also has help unlike SimpleHTTPServer, so I could figure out how to make it serve from a specific folder and thru a specific port: `twistd -no web -p 3003 --path=resources/public/` – onetom Dec 20 '14 at 20:12
  • excellent and clear answer and good info about installing it on Ubuntu. Also you can use `-p 80` for setting port number with `sudo` (in Ubuntu run: `sudo twistd -no web -p 80`) – S.M.Mousavi Jul 07 '16 at 17:56
  • This works great except that trying to start multiple is messy. You have to specify a `--pidfile` and `--logfile` to avoid clashes. Would be great if the authors could fix this. `SimpleHTTPServer` doesn't require this. – Sridhar Sarnobat Oct 22 '16 at 19:58
  • 1
    @Sridhar-Sarnobat From memory it logs to stdout by default so you shouldn't need to customise that. Pidfile is created in the current directory by default also so as long as you're starting the server in separate folders you should be fine. However, the pidfile is not required when not forking to the background so it can be disabled with `pidfile=` (leaving the right side empty disables pidfile) – Peter Gibson Oct 23 '16 at 23:23
  • How twistd can live reload when the file changes? – soarinblue Nov 16 '16 at 09:12
  • 1
    I'm on macOS 10.13, this doesn't seem to be pre-installed anymore – setholopolus Mar 27 '19 at 18:21
  • 1
    If you're using conda, `conda install twisted` – BallpointBen Apr 09 '20 at 19:10
35

1.0 includes a http server & util for serving files with a few lines of code.

package main

import (
    "fmt"; "log"; "net/http"
)

func main() {
    fmt.Println("Serving files in the current directory on port 8080")
    http.Handle("/", http.FileServer(http.Dir(".")))
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

Run this source using go run myserver.go or to build an executable go build myserver.go

pd40
  • 3,187
  • 3
  • 20
  • 29
  • Great answer. This runs faster than SimpleHTTPServer and nodejs solution. :) Is there any way I can add username and password to the download? – Ajax May 22 '16 at 21:47
22

Try webfs, it's tiny and doesn't depend on having a platform like node.js or python installed.

Hudon
  • 1,636
  • 18
  • 28
  • 1
    looks like you have to compile it? Didn't see any binaries for download. – BrainSlugs83 Apr 04 '14 at 13:40
  • 3
    yes, unless your distro has it. Debian and Ubuntu have it: `apt-get install webfs` – Hudon Apr 04 '14 at 17:41
  • 4
    I did a `brew install webfs` on my Mac which resulted in ` /usr/local/Cellar/webfs/1.21: 5 files, 96K, built in 15 seconds`. Afterwards I could just say `webfsd -F -p 3003 -r resources/public/ -f index.html` to achieve the same as `twistd -no web -p 3003 --path=resources/public/`. It's a bit wordy so not obvious to remember but good to know as an alternative to twistd or SimpleHTTPServer. – onetom Dec 20 '14 at 20:18
  • Much better than the other solutions. It's very small, very fast and provided as an OS package. It also supports SSL and can run as a system daemon. – Federico Nov 07 '19 at 15:04
15

If you use Mercurial, you can use the built in HTTP server. In the folder you wish to serve up:

hg serve

From the docs:

export the repository via HTTP

    Start a local HTTP repository browser and pull server.

    By default, the server logs accesses to stdout and errors to
    stderr. Use the "-A" and "-E" options to log to files.

options:

 -A --accesslog       name of access log file to write to
 -d --daemon          run server in background
    --daemon-pipefds  used internally by daemon mode
 -E --errorlog        name of error log file to write to
 -p --port            port to listen on (default: 8000)
 -a --address         address to listen on (default: all interfaces)
    --prefix          prefix path to serve from (default: server root)
 -n --name            name to show in web pages (default: working dir)
    --webdir-conf     name of the webdir config file (serve more than one repo)
    --pid-file        name of file to write process ID to
    --stdio           for remote clients
 -t --templates       web templates to use
    --style           template style to use
 -6 --ipv6            use IPv6 in addition to IPv4
    --certificate     SSL certificate file

use "hg -v help serve" to show global options
Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
12

Here's another. It's a Chrome Extension

Once installed you can run it by creating a new tab in Chrome and clicking the apps button near the top left

It has a simple gui. Click choose folder, then click the http://127.0.0.1:8887 link

enter image description here

https://www.youtube.com/watch?v=AK6swHiPtew

gman
  • 100,619
  • 31
  • 269
  • 393
10

I found python -m http.server unreliable—some responses would take seconds.

Now I use a server called Ran https://github.com/m3ng9i/ran

Ran: a simple static web server written in Go

Colonel Panic
  • 132,665
  • 89
  • 401
  • 465
9

Also consider devd a small webserver written in go. Binaries for many platforms are available here.

devd -ol path/to/files/to/serve

It's small, fast, and provides some interesting optional features like live-reloading when your files change.

gman
  • 100,619
  • 31
  • 269
  • 393
5

If you have PHP installed you could use the builtin server.

php -S 0:8080
user1461607
  • 2,416
  • 1
  • 25
  • 23
4

give polpetta a try ...

npm install -g polpetta

then you can

polpetta ~/folder

and you are ready to go :-)

ggorlen
  • 44,755
  • 7
  • 76
  • 106
3

Using Servez as a server

  1. Download Servez
  2. Install It, Run it
  3. Choose the folder to serve
  4. Pick "Start"
  5. Go to http://localhost:8080 or pick "Launch Browser"

servez

Note: I threw this together because Web Server for Chrome is going away since Chrome is removing support for apps and because I support art students who have zero experience with the command line

gman
  • 100,619
  • 31
  • 269
  • 393
2

Yet another node based simple command line server

https://github.com/greggman/servez-cli

Written partly in response to http-server having issues, particularly on windows.

installation

Install node.js then

npm install -g servez

usage

servez [options] [path]

With no path it serves the current folder.

By default it serves index.html for folder paths if it exists. It serves a directory listing for folders otherwise. It also serves CORS headers. You can optionally turn on basic authentication with --username=somename --password=somepass and you can serve https.

gman
  • 100,619
  • 31
  • 269
  • 393
1

I like live-server. It is fast and has a nice live reload feature, which is very convenient during developpement.

Usage is very simple:

cd ~/Sites/
live-server

By default it creates a server with IP 127.0.0.1 and port 8080.

http://127.0.0.1:8080/

If port 8080 is not free, it uses another port:

http://127.0.0.1:52749/

http://127.0.0.1:52858/

If you need to see the web server on other machines in your local network, you can check what is your IP and use:

live-server --host=192.168.1.121

And here is a script that automatically grab the IP address of the default interface. It works on macOS only.

If you put it in .bash_profile, the live-server command will automatically launch the server with the correct IP.

# **
# Get IP address of default interface
# *
function getIPofDefaultInterface()
{
    local  __resultvar=$1

    # Get default route interface
    if=$(route -n get 0.0.0.0 2>/dev/null | awk '/interface: / {print $2}')
    if [ -n "$if" ]; then
            # Get IP of the default route interface
            local __IP=$( ipconfig getifaddr $if )
            eval $__resultvar="'$__IP'"
    else
        # Echo "No default route found"
        eval $__resultvar="'0.0.0.0'"
    fi
}

alias getIP='getIPofDefaultInterface IP; echo $IP'

# **
# live-server
# https://www.npmjs.com/package/live-server
# *
alias live-server='getIPofDefaultInterface IP && live-server --host=$IP'
nico
  • 1,130
  • 2
  • 12
  • 26
0

I've been using filebrowser for the past couple of years and it is the best alternative I have found.

Features I love about it:

  • Cross-platform: It supports Linux, MacOs and Windows (+). It also supports docker (+).
  • Downloading stuff is a breeze. It can automatically convert a folder into zip, tar.gz and etc. for transferring folders.
  • You can file or folder access to every use.

enter image description here

Amir Pourmand
  • 519
  • 6
  • 17
  • 1
    Does this serve up files directly over http in a way that can be used by web developers? It looks to be only a file browser. – Drew Noakes Jul 18 '22 at 01:54
  • Yes, you can access it via REST API. See [here](https://github.com/filebrowser/filebrowser/issues/1079) and [here](https://github.com/filebrowser/docs/issues/1). – Amir Pourmand Jul 18 '22 at 09:45
0

miniserve

miniserve

  • cross platform
  • single executable file
  • lightweight ( < 2MB for Windows / Linux x86 )
miniserve . --index index.html

Vercel serve (node.js)

If node.js is installed, I recommended vercel serve

# for node.js >= v14
npm install --global serve

# for node.js <= v13
npm install --global serve@13
serve

http-server (node.js)

http-server latest version does not work ( see issue ), but v13 works

npm install --global http-server@13
http-server
Steely Wing
  • 16,239
  • 8
  • 58
  • 54