phaser-wind
v0.9.1
Published
Wind theme like Tailwind CSS for Phaser games
Maintainers
Readme
🌪️ Phaser Wind
Tired of fighting with Phaser layouts and colors?
Love Tailwind CSS but stuck with Phaser?
Welcome to Phaser Wind - bring the joy and simplicity of Tailwind-like design tokens to Phaser games! 🎮✨
🎯 Why Phaser Wind?
The Problem 😫
// Ugh... more magic numbers and random colors
const button = this.add.text(100, 50, 'Click me!', {
fontSize: '18px', // Is this too big? Too small? 🤷♂️
fill: '#3B82F6', // What color is this again?
backgroundColor: '#1F2937', // Does this even look good?
});
const title = this.add.text(200, 100, 'Game Title', {
fontSize: '32px', // Different magic number...
fill: '#EF4444', // Another random hex...
});The Solution 🌟
// No theme needed. Just import and go!
import { Color, FontSize } from 'phaser-wind';
// Clean, semantic, consistent!
const button = this.add.text(100, 50, 'Click me!', {
fontSize: FontSize.css('lg'), // Clear intention!
fill: Color.rgb('blue-500'), // Beautiful blue
backgroundColor: Color.rgb('gray-800'), // Perfect contrast
});
const title = this.add.text(200, 100, 'Game Title', {
fontSize: FontSize.css('3xl'), // Clearly bigger!
fill: Color.rgb('red-500'), // Vibrant red
});🚀 Features
- 🎨 Complete Tailwind-like Color Palette - 22 families × 11 shades
- 📐 Semantic Font Sizes - From
xsto6xl - 🧩 Default constants ready-to-use -
Color,FontSize,Spacing,Radius,Shadow - 🧭 Optional theme system (typed) - Add your own tokens with strong typing
- 🔧 TypeScript First - Full type safety and IntelliSense
- 🎮 Phaser Ready - Global plugin for easy access in scenes
- 🌈 Consistent Design - No more guessing colors and sizes
- 📦 Tiny Bundle - Great DX, minimal overhead
📦 Installation
npm install phaser-wind
# or
yarn add phaser-wind
# or
pnpm add phaser-wind🌐 UMD/CDN (JavaScript)
If you prefer not to use TypeScript or want to include the library via CDN, you can use the UMD build:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/phaser-wind.min.js"></script>The library will be available globally as window.PhaserWind. You can use it like this:
// Use color utilities
const blueColor = window.PhaserWind.Color.rgb('blue-500');
const fontSize = window.PhaserWind.FontSize.css('lg');
// Create styled text
const text = scene.add.text(100, 50, 'Hello World', {
fontSize: fontSize,
fill: blueColor
});⚠️ Note: While UMD builds are available, we strongly recommend using TypeScript for better type safety, IntelliSense, and development experience. The TypeScript version provides better error detection and autocomplete features.
🎨 Color System (no theme)
Complete Palette
Access all Tailwind colors with semantic naming:
import { Color } from 'phaser-wind';
// RGB strings (for Phaser text styles)
const blueText = Color.rgb('blue-500'); // 'rgb(59, 130, 246)'
const redButton = Color.rgb('red-600'); // 'rgb(220, 38, 38)'
// Hex numbers (for Phaser graphics)
const greenRect = Color.hex('green-400'); // 0x4ADE80
const purpleCircle = Color.hex('purple-300'); // 0xD8B4FE
// Basic colors
const blackText = Color.rgb('black'); // 'rgb(0, 0, 0)'
const whiteBackground = Color.hex('white'); // 0xFFFFFFAvailable Colors
Grays: slate, gray, zinc, neutral, stone
Colors: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose
Shades: 50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950
📏 Font Size System (no theme)
Semantic Sizing
Stop guessing font sizes and use semantic tokens:
import { FontSize } from 'phaser-wind';
// Get pixel values
const smallText = FontSize.px('sm'); // 14
const normalText = FontSize.px('base'); // 16
const largeTitle = FontSize.px('3xl'); // 30
// Get CSS strings (perfect for Phaser)
const buttonText = FontSize.css('lg'); // '18px'
const heroTitle = FontSize.css('6xl'); // '60px'
// Get rem values (if needed)
const responsiveText = FontSize.rem('xl'); // 1.25Font Size Scale
| Token | Pixels | Use Case |
| ------ | ------ | ----------------------- |
| xs | 12px | Small labels, captions |
| sm | 14px | Body text, descriptions |
| base | 16px | Default text size |
| lg | 18px | Slightly larger text |
| xl | 20px | Subheadings |
| 2xl | 24px | Headings |
| 3xl | 30px | Large headings |
| 4xl | 36px | Hero text |
| 5xl | 48px | Display text |
| 6xl | 60px | Giant display text |
🧪 Strong typing (no theme)
All APIs are strongly typed. Invalid tokens break at compile time:
import { Color, FontSize, Spacing, Radius, Shadow } from 'phaser-wind';
// ✅ OK
Color.rgb('blue-500');
FontSize.css('lg');
Spacing.px('16');
Radius.css('sm');
Shadow.get('md');
// ❌ Compile-time errors
// Color.rgb('blue-501');
// FontSize.css('huge');
// Spacing.px('97');
// Radius.css('xxl');
// Shadow.get('mega');🧱 Token Reference
Colors
- Families:
slate,gray,zinc,neutral,stone,red,orange,amber,yellow,lime,green,emerald,teal,cyan,sky,blue,indigo,violet,purple,fuchsia,pink,rose - Shades:
50,100,200,300,400,500,600,700,800,900,950 - Special:
black,white
Font Size
- Keys:
xs,sm,base,lg,xl,2xl,3xl,4xl,5xl,6xl
Spacing
- Keys (px scale ×4):
0,px(=1),0.5,1,1.5,2,2.5,3,3.5,4,5,6,7,8,9,10,11,12,14,16,20,24,28,32,36,40,44,48,52,56,60,64,72,80,96
Radius
- Keys:
none,sm,default,md,lg,xl,2xl,3xl,full
Shadow
- Default keys:
sm,md,lg,xl,2xl,inner
🎨 Theming
Phaser Wind also provides a typed theme system via a Phaser plugin. You get the same API surface (color, fontSize, spacing, radius, font, shadow) but narrowed to your custom tokens.
1) Create a theme
import { createTheme, type CreateTheme } from 'phaser-wind';
export const theme = createTheme({
fonts: {
primary: 'Inter, system-ui, sans-serif',
display: 'Orbitron, monospace',
},
fontSizes: {
// optional overrides
},
colors: {
primary: 'blue-600',
background: 'slate-900',
danger: 'red-500',
},
spacing: {
gutter: 24,
},
radius: {
card: 12,
},
effects: {
glow: { blur: 8, offsetX: 0, offsetY: 0, alpha: 0.6 },
},
} satisfies CreateTheme<any>);
export type ThemeType = typeof theme;2) Install the plugin in Phaser
import {
PhaserWindPlugin,
PHASER_WIND_KEY,
defaultLightTheme,
} from 'phaser-wind';
import { theme } from './theme';
new Phaser.Game({
plugins: {
global: [
{
key: PHASER_WIND_KEY,
plugin: PhaserWindPlugin,
mapping: PHASER_WIND_KEY, // scene.pw
data: { theme }, // or { theme: defaultLightTheme }
},
],
},
});3) How to get strong types in your scene
3.1 Lazy way. Define a module and all scenes should be have the "pw" instance
// src/my-theme.ts
import 'phaser';
import type { PhaserWindPlugin } from 'phaser-wind';
import type { ThemeType } from './theme';
const theme = const theme = createTheme({
colors: {
brand: 'purple-600',
danger: 'red-500',
}
});
export type ThemeType = typeof theme;
declare module 'phaser' {
interface Scene {
pw: PhaserWindPlugin<ThemeType>;
}
}
// In your scene
class MyCustomScene extends Phaser.Scene {
create(): void {
this.pw // <-- Valid instance in your ts file3.1 - Cast way
The original Phaser.Scene does not know the pw from Phaser-wind. You can make a simple cast to solve this problem
import Phaser from 'phaser';
import { type ThemeType } from 'src/theme.ts' // In your project
class MyCustomScene extends Phaser.Scene {
create(): void {
const { pw } = (this as unknown as SceneWithPhaserWind<Theme>); // cast to get the pw property
this.cameras.main.setBackgroundColor(pw.color.slate(900));
this.add
.text(300, 100, 'Primary color', {
fontSize: pw.fontSize.css('2xl'), // use the pw property to get the font size
color: pw.color.rgb('primary'), // use the pw property to get the color with type safety
})
.setOrigin(0.5);3.2 - Inheritance way
Phaser-wind export an abstract class to type the Phaser.Scene and add the attribute pw.
import Phaser from 'phaser';
import { type ThemeType } from 'src/theme.ts' // In your project
class PreviewScene extends SceneWithPhaserWind<ThemeType> { // Inherit from SceneWithPhaserWind to get the pw property
create(): void {
const { color, fontSize, spacing, radius, font, shadow } = this.pw; // Don't need to cast because we're using the generic type
// ✅ Type-narrowed to your theme
color.rgb('primary');
fontSize.css('lg');
spacing.px('gutter');
radius.css('card');
font.family('display');
shadow.get('glow');
// ❌ Compile-time errors
// color.rgb('blue-501');
// spacing.px('unknown');🎮 Real Game Example
You can check some examples in our Storybook in this clicking here.
🎨 Pre-built Themes
import {
PhaserWindPlugin,
PHASER_WIND_KEY,
defaultLightTheme,
// or defaultDarkTheme
} from 'phaser-wind';
import { theme } from './theme';
new Phaser.Game({
plugins: {
global: [
{
key: PHASER_WIND_KEY,
plugin: PhaserWindPlugin,
mapping: PHASER_WIND_KEY, // scene.pw
data: { theme: defaultLighTheme }, // or { theme: defaultDarkTheme }
},
],
},
});🤝 Why "Wind" instead of "Tailwind"?
We love Tailwind CSS, but we're not affiliated with them. "Phaser Wind" captures the essence:
- Wind = Fast, natural, refreshing (like your development experience)
- Wind = Carries things forward (like your game development)
- Wind = Invisible but powerful (like good design tokens)
Plus, phaser-wind is way easier to type than phaser-tailwind-css-design-tokens-for-games 😉
📚 Compared to Raw Phaser
| Without Phaser Wind | With Phaser Wind |
| ------------------------ | ------------------------------- |
| fill: '#3B82F6' | fill: Color.rgb('primary') |
| fontSize: '18px' | fontSize: FontSize.css('lg') |
| tint: 0x4ADE80 | tint: Color.hex('success') |
| fontFamily: 'Arial' | fontFamily: Font.family('ui') |
| Magic numbers everywhere | Semantic, consistent tokens |
| Color picking hell | Harmonious color palettes |
| Inconsistent sizing | Perfect typography scale |
| No design system | Complete theme architecture |
🤝 Contributing
We'd love your help making Phaser Wind even better!
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT © CassinoDev
Do you want to play? Go to games.cassino.dev.
🌟 Show Your Support
If Phaser Wind makes your game development life better, give us a ⭐ on GitHub!
Happy Gaming! 🎮✨
"Making Phaser development as enjoyable as Tailwind CSS"
— The Phaser Wind Team
