🎨 WebAssembly color manipulation library Features: - ✨ Color parsing (hex, rgb, hsl, named colors) - 🎨 Color manipulation (lighten, darken, saturate, desaturate) - 🌈 Color generation (random, gradients, palettes) - ♿ Accessibility (colorblind simulation, contrast, WCAG) - 📏 Color distance (CIE76, CIEDE2000) - 🎯 Color spaces (RGB, HSL, HSV, Lab, LCH) - 🏷️ 148 CSS/X11 named colors Bundle size: 132KB Performance: ~0.1ms per operation 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
8.2 KiB
CLAUDE.md
This file provides guidance to Claude Code when working with this repository.
Project Overview
pastel-wasm is a WebAssembly color manipulation library built with Rust. It provides comprehensive color operations directly in the browser with zero network latency.
Key Stats:
- Bundle size: 132KB (WASM)
- Language: Rust + WebAssembly
- Target: Modern browsers with WASM support
- Dependencies: Minimal (wasm-bindgen, serde, rand, getrandom)
Architecture
Project Structure
pastel-wasm/
├── src/
│ ├── lib.rs # Main WASM bindings and exported functions
│ ├── color.rs # Core color type and conversions
│ └── named.rs # Named colors database (148 CSS/X11 colors)
├── pkg/ # Build output (generated by wasm-pack)
│ ├── pastel_wasm.js
│ ├── pastel_wasm.d.ts
│ └── pastel_wasm_bg.wasm
├── Cargo.toml # Rust dependencies and configuration
├── package.json # NPM package configuration
├── README.md # User documentation
└── example.html # Interactive demo
## Color Implementation
### Color Type (`src/color.rs`)
The core `Color` struct represents colors in RGB space (0.0-1.0 range):
```rust
pub struct Color {
pub r: f64,
pub g: f64,
pub b: f64,
pub a: f64,
}
Key Methods:
parse(s: &str)- Universal color parser (hex, rgb, hsl, named)to_hex()- Convert to hex stringto_hsl(),to_hsv(),to_lab(),to_lch()- Color space conversionslighten(),darken(),saturate(),desaturate()- Adjustmentsrotate_hue(),complement(),mix()- Transformationstext_color(),contrast_ratio()- Accessibility helperssimulate_protanopia/deuteranopia/tritanopia()- Color blindnessdistance_cie76(),distance_ciede2000()- Perceptual distance
Color Space Conversions
Implemented color spaces:
- RGB ↔ HSL (Hue, Saturation, Lightness)
- RGB ↔ HSV (Hue, Saturation, Value)
- RGB → XYZ → Lab (CIELab, perceptually uniform)
- Lab → LCH (Lightness, Chroma, Hue)
Conversion accuracy:
- Uses D65 illuminant for XYZ conversions
- Implements proper gamma correction for sRGB
- Perceptually accurate Lab/LCH calculations
Named Colors (src/named.rs)
Contains 148 CSS/X11 named colors as const data:
pub const NAMED_COLORS: &[NamedColor] = &[
NamedColor { name: "red", hex: "#ff0000" },
// ... 147 more
];
WASM Bindings (src/lib.rs)
All exported functions are annotated with #[wasm_bindgen]:
Categories:
- Color Information -
parse_color() - Color Manipulation -
lighten_color(),darken_color(), etc. - Color Generation -
generate_random_colors(),generate_gradient(),generate_palette() - Accessibility -
get_text_color(),simulate_*(),calculate_contrast() - Named Colors -
get_all_named_colors(),search_named_colors() - Utilities -
color_distance(),version()
Return types:
- Simple functions return
Result<String, JsValue>(hex colors) - Complex functions return
Result<JsValue, JsValue>(serialized objects) - Uses
serde_wasm_bindgenfor JS ↔ Rust serialization
Building
Prerequisites
# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install wasm-pack
cargo install wasm-pack
Build Commands
# Build for bundler (Webpack, Rollup, Vite)
wasm-pack build --target bundler --out-dir pkg
# Build for web (vanilla JS)
wasm-pack build --target web --out-dir pkg-web
# Build for Node.js
wasm-pack build --target nodejs --out-dir pkg-node
# Build all targets
npm run build:all
Build Configuration
Cargo.toml optimizations:
opt-level = "s"- Optimize for sizelto = true- Link-time optimizationcodegen-units = 1- Better optimizationstrip = true- Remove debug symbols
wasm-opt flags:
--enable-bulk-memory- Memory operations--enable-nontrapping-float-to-int- Modern WASM features-Os- Optimize for size
Dependencies
Core dependencies:
wasm-bindgen = "0.2"- Rust ↔ JavaScript interopserde = "1.0"- Serialization frameworkserde-wasm-bindgen = "0.6"- JS object serializationrand = "0.8"- Random number generationgetrandom = { version = "0.2", features = ["js"] }- WASM-compatible RNGjs-sys = "0.3"- JavaScript standard library bindingsweb-sys = "0.3"- Web API bindingsconsole_error_panic_hook = "0.1"- Better panic messages in browser
Testing
# Run tests in headless browsers
wasm-pack test --headless --firefox --chrome
# Run tests in specific browser
wasm-pack test --firefox
wasm-pack test --chrome
Publishing
# Build and test
npm run build
npm test
# Publish to npm
wasm-pack pack
wasm-pack publish
Integration with pastel-ui
The pastel-ui Next.js application uses this WASM module instead of the REST API:
Migration steps:
- Install:
npm install pastel-wasm - Import:
import * as pastel from 'pastel-wasm' - Initialize: Call
await pastel.init()on app load - Replace API calls with direct WASM functions
- Update types (WASM returns simpler structures than API)
Benefits for pastel-ui:
- Performance: 0ms latency vs 50-200ms API calls
- Reliability: No network errors, works offline
- Cost: Zero server costs, no rate limiting
- Privacy: Color data never leaves the browser
Development Workflow
Adding a New Function
- Implement in color.rs:
impl Color {
pub fn my_new_operation(&self) -> Self {
// implementation
}
}
- Add WASM binding in lib.rs:
#[wasm_bindgen]
pub fn my_new_operation(color: &str) -> Result<String, JsValue> {
let c = Color::parse(color).map_err(|e| JsValue::from_str(&e))?;
Ok(c.my_new_operation().to_hex())
}
- Rebuild:
wasm-pack build --target bundler --out-dir pkg
- Test in example.html:
const result = pastel.my_new_operation('#ff0099');
Debugging
Rust errors:
# Check for compile errors
cargo check
# Run clippy for lints
cargo clippy
WASM errors:
- Enable panic hook:
pastel.init()callsconsole_error_panic_hook::set_once() - Check browser console for panics
- Use
console.log()viaweb_sys::console::log_1()
Performance Considerations
Fast operations (< 0.1ms):
- Color parsing
- Simple manipulations (lighten, darken, saturate)
- Color space conversions
- Hex formatting
Medium operations (< 1ms):
- Gradient generation (10 steps)
- Palette generation
- Color distance calculations
Memory:
- Each Color instance: 32 bytes (4 × f64)
- Named colors array: ~10KB (static data)
- WASM memory grows dynamically as needed
Common Issues
Build Fails with "errno not supported"
Cause: Using pastel library directly (has CLI dependencies) Solution: Use custom color implementation (already done)
wasm-opt validation errors
Cause: Missing WASM features Solution: Add flags in Cargo.toml:
[package.metadata.wasm-pack.profile.release]
wasm-opt = ["-Os", "--enable-mutable-globals", "--enable-bulk-memory", "--enable-nontrapping-float-to-int"]
Random number generation fails in browser
Cause: Missing JS feature flag for getrandom Solution: Add to Cargo.toml:
getrandom = { version = "0.2", features = ["js"] }
Future Enhancements
Planned Features
- More color harmony schemes (square, split, analogous)
- Color palettes from images (requires image parsing)
- CMYK color space support
- Color name lookup (closest named color)
- Gradient interpolation in different color spaces (Lab, LCH)
- Batch processing optimizations
Optimization Opportunities
- SIMD operations for batch processing
- Lazy loading of named colors
- Memoization of expensive calculations
- WebWorker support for heavy operations
Resources
Project Status: Production-ready Last Updated: 2025-01-17