Compile static files into Elixir bytecode and serve them from memory
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
config
lib
test
.gitignore
LICENSE.md
README.md
mix.exs
mix.lock

README.md

ExStatic

Serve static files from memory in the Phoenix Framework.

This extension compiles all of a project's static assets (e.g. Javascript, HTML, images, etc) into Erlang modules and loads them into the Erlang VM, with the purpose of serving them fast and without a dependency on a filesystem.

The assumption is that there are not that many static files and they are not that big. There are no size checks done -- take care that your VM settings allow the kind of memory usage.

Usage

Add exstatic to your deps:

 {:exstatic, "~> 0.1"},

Then, compile your static files (by default it looks in priv/static):

 mix exstatic.compile

Now, tell your endpoint to serve the compiled files.

defmodule MyApp.Endpoint do
  use Phoenix.Endpoint, otp_app: :myapp
  
  # Serve at "/" the static files from ExStatic compiled files
  plug ExStatic.Plug,
    at: "/"

Remember, whenever you change your files, you need to run mix exstatic.compile again.

Performance

Initial tests show that the performance is about a 70% increase compared to the vanilla Plug.Static.

How it works

Static files are compiled to the plain data and also to a gzip version. Furthermore, file metadata is also compiled into accessor functions.

The module names are checksums of the original filenames (relative to the static base path, e.g. priv/static): ExStatic.Compiled.66AGY7SLJZNP4MCP256LHNA6UWRMTGUY.beam.

Each module compiles several functions, exposing the file contents and its metadata. These functions are also accessible from the ExStatic module:

ExStatic.contents("robots.txt")
ExStatic.gzip_contents("robots.txt")
ExStatic.size("robots.txt")
ExStatic.gzip_size("robots.txt")
ExStatic.content_type("robots.txt")
ExStatic.ctime("robots.txt")
ExStatic.mtime("robots.txt")

All of these functions also exist in assertion-mode:

ExStatic.mtime!("robots.txt")

Whenever a file is not found, the function crashes (the ! variant); or {:error, :nofile, filename} is returned (the normal variant).

Furthermore, there is a ExStatic.exists? function returning a boolean to check whether a given file exists.