A web application serving as both a user-friendly web interface and a REST API for Google's Closure Compiler.
The application is available at https://jscompressor.treblereel.dev/
- java 21 (GraalVM for native image)
- maven 3.8.3
- or Docker/Podman (optional)
- Clone the repository
- Run
mvn clean package - Run
java -jar ./target/quarkus-app/quarkus-run.jar
The repository contains prebuilt, self-hosted UI assets, so Java and container builds do not require Node.js. When changing UI styles or upgrading Alpine.js/Tailwind CSS, install Node.js 20 or newer and regenerate the committed assets with:
npm ci
npm run build- Clone the repository
- Run
mvn clean package -Pnative - Run
./target/jscompressor-0.1-runner
The native image is available on Docker Hub.
Run the published image:
docker pull treblereel/jscompressor:latest
docker run --detach --name jscompressor \
--publish 8080:8080 \
--volume jscompressor-cache:/volume \
treblereel/jscompressor:latestBuild the native container locally:
mvn clean package -Pnative
docker build --file src/main/docker/Dockerfile.native --tag jscompressor .
docker run --rm --publish 8080:8080 --volume jscompressor-cache:/volume jscompressorThe Publish native image GitHub Actions workflow publishes linux/amd64 images to
docker.io/treblereel/jscompressor. Configure these repository secrets before running it:
DOCKERHUB_USERNAME- Docker Hub username.DOCKERHUB_TOKEN- Docker Hub access token with permission to push the repository.
Publishing a GitHub Release publishes its Git tag, sha-<commit>, and latest image tags. The release tag
must match the closure-compiler.version property in pom.xml, for example v20260915,
or append a positive numeric revision for application fixes, for example v20260915-1.
The workflow can also be started manually with a custom image tag and an optional latest update.
It builds the native executable in the Quarkus Linux builder container, runs the native integration test,
smoke-tests the final container, and rejects fixable high or critical vulnerabilities before logging in and
pushing it. Published images include SBOM and build provenance attestations.
Note: You should be familiar with such topics like Docker root/rootless containers, selinux and such topics. For
instance, if you get permission denied error, you should check the selinux context of the volume. That is why I prefer
rootless Podman containers, that configure the context automatically.
Tips: If you are a mac user, check you build the native image for Linux. (docs docker buildx)
Tips: https://quarkus.io/guides/container-image
The application can be configured using the following environment variables:
MAX_DOWNLOAD_FILE_SIZE- Sets the maximum file/script size that can be uploaded to the server. Default is 1048576 bytes (1MB).MAX_REQUEST_BODY_SIZE(server.request-body-max-size) - Maximum complete JSON request size in bytes. Default is0: automatically uses six timesserver.download-file-max-sizeplus 65536 bytes for JSON escaping and request metadata. A positive value sets an explicit body limit. Requests above this limit return JSON HTTP 413, including chunked requests. The decoded payload still usesserver.download-file-max-size; an oversized payload within the body limit returns HTTP 400.MAX_DOWNLOAD_URLS_PER_REQUEST- Sets the maximum number of URLs that can be uploaded to the server. Default is 10.DOWNLOAD_TIMEOUT_MS- Total deadline per external URL in milliseconds, including DNS, connection attempts, redirects and body transfer. Default is 30000; must be positive. Connect and idle timeouts remain independently configurable withDOWNLOAD_CONNECT_TIMEOUT_MS(5000) andDOWNLOAD_READ_TIMEOUT_MS(10000).MAX_CACHE_DIR_SIZE- Sets the maximum size of the cache directory. Default is 1073741824 bytes (1GB). Once limit is reached, the oldest files will be deleted.RATE_LIMIT_ENABLED- Enables per-client REST rate limiting for/compileendpoints. Default istrue.RATE_LIMIT_REQUESTS_PER_MINUTE- Sets the maximum number of/compilerequests per client per minute. Default is 120.PROXY_ADDRESS_FORWARDING- TrustsX-Forwarded-*request information when set totrue. Default isfalse.TRUSTED_PROXIES- Comma-separated proxy IP addresses or CIDR ranges allowed to provide forwarded request information. Default is127.0.0.1.
All of the above can be set in the application.properties file or provided as environment variables to the docker container.
Server defaults are defined in src/main/resources/application.properties. The container image uses these defaults, except for CACHE_DIR=/volume.
The HTTP server (quarkus.http.limits.max-body-size) and any reverse proxy may impose a lower body limit. Configure those separately when increasing the application limits; responses rejected by those layers may use their own error format.
External scripts must use public HTTP or HTTPS URLs. Loopback, private, link-local, multicast, and reserved
addresses are rejected. Every redirect is validated again, and connections are pinned to the validated DNS
address to prevent DNS rebinding.
Bodies are read with a streaming byte limit, including chunked responses. Downloads request
Accept-Encoding: identity; other response content encodings are rejected. A timed-out DNS lookup may
finish in the background, but its result cannot start a connection. The complete compile request also
has its existing 120-second timeout.
When running behind a reverse proxy, set PROXY_ADDRESS_FORWARDING=true and configure TRUSTED_PROXIES
with the proxy's address or network. The proxy must replace client-provided X-Forwarded-* headers rather
than append to untrusted values. Forwarded headers remain ignored when proxy forwarding is disabled or the
direct peer is not trusted.
The application provides an OpenAPI specification at openapi.yaml
Prometheus metrics are available at /metrics. Quarkus provides HTTP request duration and status metrics;
application metrics use the jscompressor_ prefix and cover compilation outcomes and duration, active
compilations, source and output sizes, cache usage, cached files, and cache evictions.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
If you like this project, consider donating to the developer:
Please use the Github Issues page to report any bugs or request new features.