
bowdy • A fast CSS Preprocessor
Typed • VM & JIT Compiler • Written in Nim language
nimble install bowdy / clue install bowdy --build / npm install bowdy
bowdy transpiles BASS files to standard CSS. It is written in Nim and designed for fast compilation, a typed system that catches errors early, and syntax that stays close to CSS while adding variables, nesting, mixins, control flow, and modules.
BASS files use the .bass extension and compile to .css.
Features
- Fast stack-based VM & JIT Compiler
- Typed system for CSS values (
color, length, number, etc.) with compile-time checks
- Familiar CSS syntax with indentation or brace blocks
- Variables (
var, const) with optional type annotations and export (*)
- Nesting with parent selector
&, combinators, and comma-separated selectors
- Reusable mixins with typed parameters and named arguments
- Control flow (
if / elif / else, for, while, case / of) and functions (fn / func)
- Module imports (
import "./vars.bass") and package imports (pkg/)
- Modern CSS passthrough: custom properties,
var(), calc(), color-mix(), gradients, and at-rules
- Source maps, bundling, and pretty-printed output
Syntax Showcase
All examples are minified by default. Add --pretty for formatted output.
1. Variables
var $primary = #0d6efd
var $radius = 4px
.card
color: $primary
border-radius: $radius
.card{color:#0d6efd;border-radius:4px}
2. Nesting
.card
color: gray
&:hover
color: black
.title
font-weight: bold
.card{color:gray}.card:hover{color:black}.card .title{font-weight:bold}
3. Mixins
mixin btn(color: color) {
color: $color
border-radius: 4px
}
.a
@btn(red)
.a{color:red;border-radius:4px}
4. Control Flow and Code Generation
for $i in range(1, 3):
.p-${$i}
z-index: $i
.p-1{z-index:1}.p-2{z-index:2}.p-3{z-index:3}
Other constructs:
var debug = true
.a
if $debug:
outline: 1px
else:
outline: none
for also iterates over arrays of objects (for $s in [{k:0,v:0}, {k:1,v:0.25rem}]), while, and case / of are available.
5. Imports
// _vars.bass
var $accent* = #0d6efd
var $radius* = 4px
// main.bass
import "./_vars.bass"
.a
color: $accent
border-radius: $radius
.a{color:#0d6efd;border-radius:4px}
Export with *, import relative files or packages.
6. Functions
fn dbl($n: int): int
return $n * 2
var $p = dbl(21)
.a { z-index: $p }
.a{z-index:42}
func is an alias for fn. Functions support overloading and forward declarations.
7. Embed bowdy in your Nim app
import bowdy gives two high-level calls that never quit the process.
Both return a bowdyCompileResult (ok, css, warnings, error):
import bowdy
let r = compileStylesheet("var $primary = #0d6efd\n.card\n color: $primary")
if r.ok:
echo r.css
for w in r.warnings: echo w
else:
echo "build failed: " & r.error
let f = compileStylesheetFile("styles/main.bass", pretty = true)
Documentation
Contributing
License
bowdy is released under the LGPL-3.0-or-later license. Made by Humans from OpenPeeps.
Copyright © 2026 OpenPeeps & Contributors — All rights reserved.