drip
A CLI that vendors Lustre UI elements (Gleam, CSS, and sometimes a little browser FFI) straight into your project. There is no component library to depend on: drip add button copies the element’s source into your src/ui/ directory, wires its styles in, and gets out of the way.
Install
drip is a build-time tool, so add it as a dev dependency:
gleam add drip --dev
Quick start
From the root of an existing Gleam + Lustre project:
gleam run -m drip -- init # scaffold the stylesheets
gleam run -m drip -- list # see which elements are available
gleam run -m drip -- add button # vendor an element and its dependencies
gleam run -m drip -- remove button # remove previously vendored elements
init writes the design tokens and wires them into your entry stylesheet; add copies elements into src/ui/ and keeps the index in sync. Every command that writes files prints a diff of what it touched:
Vendored 1 element into src/ui.
+ created src/ui/button.css
+ created src/ui/button.gleam
~ modified src/ui/index.css
Further documentation, the element catalog, and live examples are available at https://drip.pink.
Commands
| Command | What it does |
|---|---|
init | Scaffolds theme.css, the generated index.css, and wires up your entry stylesheet. |
list | Lists the elements in the registry, marking which are already vendored. |
add <element>... | Vendors one or more elements and their dependencies into src/<prefix>/. |
remove <element>... | Deletes the named elements’ files. |
Flags:
| Flag | Commands | Description |
|---|---|---|
--prefix <dir> | init | Directory under src/ that elements vendor into, saved to [tools.drip] in your gleam.toml (default: ui). |
--source <url-or-path> | init | Registry to vendor from, a URL or local path, saved to [tools.drip] in your gleam.toml (default: the latest GitHub release). |
--force | init, add | Overwrite files that already exist on disk. |
Pass --help to any command (for example gleam run -m drip -- add --help) to see its usage.
How it works
Elements land flat in src/<prefix>/, which defaults to src/ui/. You own every file that lands there.
initfetchestheme.css(your design tokens) from the source, generatessrc/<prefix>/index.css(it imports the theme plus every vendored element), and adds an@importfor the index to your entry stylesheet. The index is regenerated on everyaddandremove.addvendors each element you name along with everything it depends on in turn, soadd fieldalso brings inseparator.removedeletes only the elements you name. It does not cascade to dependencies, since another vendored element might still rely on them.- Re-running
addleaves files already on disk untouched unless you pass--force.
Two kinds of follow-up are printed as next steps rather than done for you: Hex packages an element needs (gleam add ...) and any browser FFI an element ships (call <name>.init() at app start).
Each row in the output is prefixed with what happened to the file:
| Glyph | Meaning |
|---|---|
+ | created |
~ | modified |
= | unchanged or skipped |
- | deleted |
Configuration
drip reads its settings from a [tools.drip] table in your gleam.toml:
[tools.drip]
prefix = "ui"
source = "https://github.com/scott-ray-wilson/drip/releases/latest/download"
Both keys are optional, and the defaults above apply when they are absent. init --prefix and init --source write your choices here so later commands stay consistent. The prefix must be a valid Gleam module path (lowercase identifier segments such as ui or lib/ui), because vendored modules are imported through it.
Custom registries
A source is everything drip reads from: a registry.json index alongside the element files and theme.css it references. The default source is the latest GitHub release, but source can point at any HTTP(S) URL or a local directory, which is handy for testing your own catalog. The index looks like this:
{
"schema_version": 1,
"name": "drip",
"homepage": "https://drip.pink",
"elements": [
{
"name": "field",
"description": "A layout that pairs a form control with its label, description, and message.",
"category": "forms",
"registry_dependencies": ["separator"],
"dependencies": [],
"files": ["field.css", "field.gleam"]
}
]
}
registry_dependencies are other elements, resolved and vendored automatically; dependencies are Hex packages, surfaced as gleam add steps. Because elements vendor flat, files must be plain file names (no /, \, or ..). If a registry advertises a schema_version newer than your installed drip supports, the CLI will ask you to update.
Development
gleam test # run the tests
gleam build # compile the CLI
This package lives in the drip monorepo. See CONTRIBUTING.md for prerequisites and the full workflow.