created_at2021-03-03 19:02:25.435911
updated_at2023-11-26 16:30:44.792247
descriptionDev server with auto-reload, static file server, proxy support, and more. Language and framework agnostic. This is the CLI app, but Penguin exists as a library, too.
Lukas Kalbertodt (LukasKalbertodt)



Penguin: language and framework agnostic dev server

CI status of main App version on Library version on

Penguin is a dev server featuring live-reloading, a file server, proxy support, and more. It is language and framework agnostic, so it works for basically any web project. Browser sessions can reload themselves (e.g. when a file changes) or show an overlay with a custom message (e.g. the compiler error).

Penguin is available both as a command line application (penguin-app on and as a library. For for more information on the library, see its documentation. The rest of this document will mainly talk about the CLI app.


  • penguin serve . serves the current directory as file server

  • penguin proxy localhost:3000 forwards all requests to http://localhost:3000.

  • -m uri_path:fs_path allows you to mount additional directories in the router.

  • penguin reload reloads all active browser sessions.


For now, you have to compile the app yourself. It's easiest to install it from

cargo install penguin-app

Don't worry about the -app suffix: the installed binary is called penguin.

CLI Usage

There are two main "entry points": penguin proxy <target> and penguin serve <directory>. The proxy subcommand is useful if you have some (backend) webserver on your own, e.g. to provide an API. The serve subcommand is useful if you only have static files that need to be served, e.g. for static site generators or backend-less single page applications.

In either case, you can mount additional directories at an URL path with -m/--mount. The syntax is -m <url-path>:<fs-path>, for example -m fonts:frontend/static. An HTTP request for /fonts/foo.woff2 would be answered with the file frontend/static/foo.woff2 or with 404 if said file does not exist.

All paths that are served by Penguin are automatically watched by default. This means that any file change in any of those directories will lead to all browser sessions reloading automatically. You can watch additional paths (that are not mounted/served) with -w/--watch.

Reloading all active browser sessions can also be done manually via penguin reload. This is intended to be used at the end of your build scripts. Note that Penguin is not a build system or task executor! So you are mostly expected to combine it with other tools, like watchexec, cargo watch or others. I am also working on floof, which is a WIP file-watcher and task-runner/build-system that uses Penguin under the hood to provide a dev server.

Penguins output can be modified with -v/-vv and the log level (set via -l or RUST_LOG).

For the full CLI documentation run penguin --help or penguin <subcommand> --help.

Project status and "using in production"

This project is fairly young and not well tested. However, it already serves as a useful development tool for me. I'm interested in making it useful for as many people as possible without increasing the project's scope too much.

I am looking for Community Feedback: please speak your mind in this issue. Especially if you have a use case that is not yet well served by Penguin, I'd like to know about that!

"Can I use Penguin in production?". No, absolutely not! This is a development tool only and you should not open up a Penguin server to the public. There are probably a gazillion attack vectors.

Versioning and stability guarantees

The app and library are versioned independently from one another. The project mostly follows the usual semantic versioning guidelines.

  • The required Rust version (MSRV) can be bumped at any time, even with minor releases. This will change once this project reaches 1.0.

  • All UI (HTML/CSS) this app/lib produces is subject to change even with minor version bumps. For example, you cannot rely on a specific "directory listing" of the file server.

  • HTTP headers in server replies might be added (or potentially even removed) even in minor version bumps.


Licensed under either of Apache License, Version 2.0 or MIT license at your option. Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Commit count: 128

cargo fmt