A declarative layout library for Lustre, inspired by elm-ui.
Build beautiful, responsive layouts with a type-safe API that automatically generates CSS. No more wrestling with stylesheets!
✨ Declarative API - Describe what you want, not how to build it
🎯 Type-Safe - Leverage Gleam's type system for compile-time safety
🚀 Zero CSS - All styles generated automatically
📦 Modular - 4 focused modules with 116 functions
📖 Well Documented - Every function includes examples
⚡ Fast - Efficient compilation (~0.9s) and runtime
gleam add lustre_stylishimport lustre/stylish as el
import lustre/stylish/font
import lustre/stylish/background
import lustre/stylish/border
pub fn view() {
el.el([
background.color(el.rgb(0.95, 0.95, 0.95)),
el.padding(20),
border.rounded(8),
border.shadow(border.ShadowConfig(
offset: #(0.0, 2.0),
blur: 8.0,
size: 0.0,
color: el.rgba(0.0, 0.0, 0.0, 0.1),
)),
],
el.column([el.spacing(15)], [
el.el([
font.size(24),
font.bold,
font.color(el.rgb(0.2, 0.2, 0.3)),
], el.text("Hello, Lustre Stylish!")),
el.paragraph([], [
el.text("Build beautiful layouts with "),
el.el([font.italic], el.text("zero CSS")),
el.text("!"),
]),
])
)
}Layout primitives, sizing, spacing, alignment, colors, transforms, nearby elements, rendering, mapping, responsive design, and debugging.
Font families, sizes, weights, colors, alignment, and decorations.
Border styling, rounded corners, box shadows, and glows.
Colors, gradients, and background images.
Mouse and focus event handlers for interactive elements.
ARIA landmarks, headings, live regions, and semantic HTML for assistive technologies.
Keyed layout elements for optimized rendering of dynamic lists.
Type definitions and documentation for form inputs. This module provides the API surface matching elm-ui's Element.Input but requires using native Lustre HTML elements for actual implementation. See module documentation for recommended patterns.
Total: 130+ functions across 8 modules
Lustre Stylish follows elm-ui's proven philosophy:
- Layout is not styling - Separate concerns clearly
- Impossible states are impossible - Type safety prevents errors
- Composable by default - Build complex UIs from simple pieces
- No magic strings - Everything is typed and documented
Many helpers are constants (not functions), providing zero-cost abstractions:
// ✅ Constants - no () needed
el.none
el.fill
el.shrink
el.scrollbars
el.clip
el.pointer
el.space_evenly
el.center_x
el.center_y
font.bold
font.italic
font.underline
font.center
font.serif
font.sans_serif
border.solid
border.dashed
border.dotted
// ⚠️ Functions - () required
el.padding(20)
el.spacing(10)
el.width(el.px(100))
font.size(16)
border.rounded(8)Responsive Layout
el.row([
el.width(el.fill),
el.spacing(20),
el.padding(15),
], [
el.el([el.width(el.fill_portion(2))], content1),
el.el([el.width(el.fill_portion(1))], content2),
])Centered Card
el.el([
el.center_x,
el.center_y,
el.padding(30),
border.rounded(12),
border.solid,
border.width(1),
border.color(el.rgb(0.8, 0.8, 0.8)),
background.color(el.rgb(1.0, 1.0, 1.0)),
], card_content)Text Styling
el.paragraph([
font.size(16),
font.family([font.typeface("Inter"), font.sans_serif]),
font.color(el.rgb(0.2, 0.2, 0.3)),
], [
el.el([font.bold], el.text("Important: ")),
el.text("All constants provide zero-cost abstractions."),
])Interactive Button
el.el([
el.padding_xy(20, 10),
el.pointer,
border.rounded(6),
background.color(el.rgb(0.2, 0.4, 0.8)),
font.color(el.rgb(1.0, 1.0, 1.0)),
font.center,
], el.text("Click me!"))Full API documentation available at https://hexdocs.pm/lustre_stylish
Or build locally:
gleam docs buildgleam build # Build the project
gleam test # Run the tests
gleam docs build # Generate documentationMIT License
- elm-ui by Matthew Griffith - The inspiration and design foundation
- Lustre by Hayleigh Thompson - The excellent Gleam web framework
- Gleam team - For the wonderful language