Documentation
Everything Packly does, in the order it does it. Run every command from your project root: Packly reads packly.ini from the current directory.
1. Install
Packly ships as 5 standalone binaries. Download the one for your platform from the latest release:
| Platform | File |
|---|---|
| Linux x64 | packly-linux-amd64 |
| Linux ARM64 | packly-linux-arm64 |
| macOS Intel | packly-macos-amd64 |
| macOS Apple Silicon | packly-macos-arm64 |
| Windows x64 | packly-windows-amd64.exe |
Linux and macOS: make it executable and put it in your PATH.
$ chmod +x packly-linux-amd64
$ sudo mv packly-linux-amd64 /usr/local/bin/packly
$ packly # prints the available commands
Windows: rename the file to packly.exe and place it in a folder listed in your PATH.
2. Quick start
Create packly.ini at your project root, or let the first packly install generate a default one, then fill it in:
[build] source = assets target = public [dependencies] bootstrap = https://github.com/twbs/bootstrap/archive/refs/tags/v5.3.3.zip confetti = https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.2/dist/confetti.module.mjs [sass] version = 1.79.2 entrypoints = styles/app.scss
Then run:
$ packly install # downloads into assets/vendor/ $ packly build # copies to public/build/ and compiles Sass $ packly build --watch # same, then rebuilds on every change
Your files are now in public/build/. See Using the files in HTML to load them in your pages.
3. packly.ini reference
If the file does not exist, the first packly install or packly build creates it with defaults. It has three sections.
[build]
| Key | Default | Meaning |
|---|---|---|
source | assets | Folder holding your own assets and the vendor/ folder. |
target | public | Public folder. Packly always writes into <target>/build/. |
ignore | empty | Comma-separated paths, relative to source, never copied to the build. Example: vendor/bootstrap when you only need its Sass sources. |
[dependencies]
One line per dependency. The key is the folder name, the value is one or more comma-separated URLs.
[dependencies] ; single file โ assets/vendor/jquery/jquery.min.js jquery = https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js ; several files in one folder leaflet = https://unpkg.com/leaflet@1.9.4/dist/leaflet.js, https://unpkg.com/leaflet@1.9.4/dist/leaflet.css ; ZIP archive โ extracted into assets/vendor/bootstrap/ bootstrap = https://github.com/twbs/bootstrap/archive/refs/tags/v5.3.3.zip
unpkg.com/leaflet/dist/leaflet.css) can return a different file tomorrow.[sass]
| Key | Default | Meaning |
|---|---|---|
version | 1.79.2 in the generated file | dart-sass version to download. Required as soon as you have entrypoints. |
entrypoints | empty | Comma-separated files, relative to source, compiled to CSS. Example: styles/app.scss, styles/admin.scss. Leave empty to skip Sass: nothing is downloaded. |
style | compressed | CSS output style: compressed (minified) or expanded (readable, handy in development). Any other value stops Packly with an error. |
sourcemap | false | Set to true to write a .css.map file next to each CSS file. |
4. packly install
$ packly install
$ packly install --force # delete and download every dependency again
- Creates
<source>/vendor/and a.gitignoreinside it that ignores everything. - Processes dependencies in alphabetical order.
- For each URL, skips it if it was already installed. Packly keeps a hidden marker file per URL, so changing a URL triggers a new download.
- A URL ending in
.zipis extracted. If the archive starts with a root folder (like GitHub archives), that folder is removed so files land directly invendor/<key>/. Folders nameddocs,site,test,tests,demo,samplesand.githubare skipped. - Any other URL is saved as a single file, named after the last part of the URL, query string removed.
Archive entries that would write outside the target folder (../) are rejected. Downloads time out after 30 seconds. Any failed download or extraction stops Packly with an error; dependencies already installed stay installed.
5. packly build
$ packly build
- Deletes
<target>/build/, then recreates it. Never put files there by hand. - Copies every file of
sourceinto it, keeping the folder structure, except.scssand.sassfiles, hidden files and folders, and paths listed inignore. - Compiles each Sass entrypoint (next section).
6. Sass
On the first build with at least one entrypoint, Packly downloads the official dart-sass release for your OS and architecture into .sass/ at your project root, with a .gitignore. This works on the same 5 platforms as Packly itself.
Each entrypoint is compiled to the same relative path, with a .css extension:
assets/styles/app.scss โ public/build/styles/app.css
By default the CSS is compressed and no source map is written. For development, switch both in packly.ini:
[sass] style = expanded sourcemap = true ; also writes public/build/styles/app.css.map
An entrypoint that does not exist only prints a warning. A Sass compilation error stops Packly and shows the dart-sass output.
To change the Sass version, edit version and delete the .sass/ folder.
7. Watch mode
$ packly build --watch
Builds once, then watches every folder of source except vendor/ and ignored paths. After a change, it waits 300 ms for other changes, then runs a full build. New folders are watched automatically. Hidden files and editor backup files (ending in ~) do not trigger a build.
packly build --watch again.Since vendor/ is not watched, run packly install then packly build after changing dependencies.
8. Using the files in HTML
Packly never touches your templates. You reference the files in /build/ yourself:
<link rel="stylesheet" href="/build/styles/app.css">
<script type="importmap">
{
"imports": {
"confetti": "/build/vendor/confetti/confetti.module.mjs"
}
}
</script>
<script type="module" src="/build/js/app.js"></script>
Then import confetti from 'confetti'; works natively in the browser.
9. Git and CI
Commit packly.ini. Packly already ignores vendor/ and .sass/. Add the build output to your own .gitignore:
public/build/
In CI or on deploy, run both commands:
$ packly install $ packly build