README.md
April 19, 2026 ยท View on GitHub
"The more you sweat in peace, the less you bleed in war." โ Norman Schwarzkopf.
โ๏ธ Features
This tool is extremely small and minimalistic, with absolutely no bells or whistles.
- Loads all static assets (e.g. images, stylesheets, scripts, etc.) into memory.
- Allows retrieval by relative path.
- Tags each asset with an appropriate Content-Type.
- Tags each asset with an ETag for efficient caching and update detection.
โฌ๏ธ Installation
Add the following dependency to your build.sbt:
libraryDependencies += "com.alecdorrington" %% "asset-loader" % "0.2.5"
Compiled with Scala 3.8.3, with no intention to explicitly support older versions.
โ๏ธ Example
This example uses fake Request and Response types to illustrate the idea in a simple manner.
The details will depend on your choice of web framework (e.g. Tapir or http4s).
import com.alecdorrington.assetloader.{Asset, AssetLoader}
val assetLoader = AssetLoader(assetsPath = "client/src/main/resources")
def handleRequest(request: Request): Response =
if request.path.startsWith("assets/") then
val assetOption: Option[Asset] = assetLoader.getAsset(request.path.dropLeft(7))
assetOption match
case Some(asset) => Response(asset)
case None => Response.NotFound
else
// ...
๐ก Server Integration
Currently, a connector exists for only a single web framework: Tapir.
In principle, any future connectors will be published as separate dependencies with the name asset-loader-{web-framework}.
Contributions are welcome!
Tapir
Tapir is a library to describe HTTP APIs and expose them as a server. A separate connector is provided to easily create a Tapir endpoint that serves static files from Asset Loader. Just add the following additional dependency:
libraryDependencies += "com.alecdorrington" %% "asset-loader-tapir" % "0.2.5"
Observe the following minimal example, using Netty and Cats Effect:
object Main extends ResourceApp.Forever:
val assets = AssetService[IO](
externalPath = "assets",
internalPath = Paths.get("src/main/resources"),
)
def run(args: List[String]) =
NettyCatsServer
.io()
.flatMap: server =>
val service = server
.host("0.0.0.0")
.port("8080")
.addEndpoints(assets.api)
Resource.make(service.start())(_.stop()).as(())
๐ฅ๏ธ Client Versions
All of the above dependencies are exclusively for the JVM. However, you may wish to access the non-JVM-specific functionality from the client as well. For this reason, each aforementioned dependency is published with a common part that is cross-compiled.
These can be installed as follows:
libraryDependencies += "com.alecdorrington" %%% "asset-loader-common" % "0.2.5"
libraryDependencies += "com.alecdorrington" %%% "asset-loader-tapir-common" % "0.2.5"
Note that you don't need to explicitly include the above if you only use this library on the server.
๐๏ธ See also
- See Scala Website Template for an example template which uses Asset Loader to build a full stack website.
- See Page Loader for a similar library which loads Scala.js webpages instead of static assets.
- This library was made using Scala Library Template.