https://github.com/callum-gander/nine-slice-frame
A modern nine-slice scaling component for React, Vue, Svelte, and Solid. Zero dependencies, tiny bundle sizes (~1KB), and native CSS performance. Perfect for scalable UI frames, borders, and pixel art interfaces.
https://github.com/callum-gander/nine-slice-frame
9-slice border-image game-ui nine-slice pixel-art react solidjs svelte typescript ui-components vue
Last synced: 29 days ago
JSON representation
A modern nine-slice scaling component for React, Vue, Svelte, and Solid. Zero dependencies, tiny bundle sizes (~1KB), and native CSS performance. Perfect for scalable UI frames, borders, and pixel art interfaces.
- Host: GitHub
- URL: https://github.com/callum-gander/nine-slice-frame
- Owner: callum-gander
- License: mit
- Created: 2025-10-01T10:48:58.000Z (8 months ago)
- Default Branch: main
- Last Pushed: 2025-10-01T17:23:40.000Z (8 months ago)
- Last Synced: 2025-10-08T19:11:39.785Z (8 months ago)
- Topics: 9-slice, border-image, game-ui, nine-slice, pixel-art, react, solidjs, svelte, typescript, ui-components, vue
- Language: TypeScript
- Homepage: https://callum-gander.github.io/nine-slice-frame/
- Size: 115 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# nine-slice-frame
[](https://www.npmjs.com/package/@nine-slice-frame/react)
[](https://www.npmjs.com/package/@nine-slice-frame/vue)
[](https://www.npmjs.com/package/@nine-slice-frame/svelte)
[](https://www.npmjs.com/package/@nine-slice-frame/solid)
[](https://opensource.org/licenses/MIT)
Modern nine-slice scaling components for React, Vue, Svelte, and Solid using CSS `border-image`.
🎯 **[Live Demo & Tester Tool](https://callum-gander.github.io/nine-slice-frame/)**
## What is Nine-Slice Scaling?
Nine-slice scaling divides an image into 9 sections, allowing it to scale to any size while preserving corner details and preventing distortion. Perfect for UI frames, borders, panels, and buttons that need to scale dynamically.
```
┌─────────┬───────────┬─────────┐
│ Corner │ Top Edge │ Corner │
│ (Fixed) │ (Scale H) │ (Fixed) │
├─────────┼───────────┼─────────┤
│ Left │ Center │ Right │
│ Edge │ (Scale │ Edge │
│(Scale V)│ Both) │(Scale V)│
├─────────┼───────────┼─────────┤
│ Corner │ Bottom │ Corner │
│ (Fixed) │ Edge │ (Fixed) │
└─────────┴───────────┴─────────┘
```
## Why Nine-Slice Scaling?
**The Problem:** Traditional image scaling stretches the entire image uniformly, distorting corners, borders, and decorative elements. This makes UI elements look unprofessional and breaks visual consistency.
**The Solution:** Nine-slice scaling keeps corners and edges crisp while only stretching the middle sections. This means:
- **Single image, infinite sizes** - One asset works for buttons, dialogs, and panels of any dimension
- **Pixel-perfect corners** - Ornate borders and rounded corners stay sharp at any scale
- **Smaller file sizes** - No need for multiple image variants for different sizes
- **Ideal for pixel art** - Preserves the crisp aesthetic of retro-style UIs
- **CSS-native performance** - Uses browser-native `border-image`, no canvas or WebGL overhead
**Common Use Cases:**
- Game UI frames and dialog boxes
- Decorative borders and panels
- Scalable buttons with ornate edges
- Retro/pixel art interfaces
- Dynamic content containers
## Why This Library?
**Zero Dependencies** - No runtime dependencies beyond your framework of choice. Each package only requires its respective framework as a peer dependency.
**Incredibly Small** - Minimal bundle impact with tiny package sizes:
- **React**: ~881B (ESM)
- **Vue**: 1.33KB / 0.67KB gzipped
- **Svelte**: 1.18KB / 0.62KB gzipped
- **Solid**: 3.09KB / 1.28KB gzipped
**Native Performance** - Uses browser-native CSS `border-image` property, not canvas rendering or heavy image manipulation libraries. Fast, efficient, and hardware-accelerated.
**Framework-Agnostic API** - Same simple, consistent API across React, Vue, Svelte, and Solid. Learn once, use everywhere.
## Installation
### React
```bash
npm install @nine-slice-frame/react
# or
pnpm add @nine-slice-frame/react
# or
yarn add @nine-slice-frame/react
```
### Vue
```bash
npm install @nine-slice-frame/vue
# or
pnpm add @nine-slice-frame/vue
# or
yarn add @nine-slice-frame/vue
```
### Svelte
```bash
npm install @nine-slice-frame/svelte
# or
pnpm add @nine-slice-frame/svelte
# or
yarn add @nine-slice-frame/svelte
```
### Solid
```bash
npm install @nine-slice-frame/solid
# or
pnpm add @nine-slice-frame/solid
# or
yarn add @nine-slice-frame/solid
```
## Usage
#### React
```tsx
import { NineSliceFrame } from '@nine-slice-frame/react';
function App() {
return (
Your content here
);
}
```
#### Vue
```vue
import { NineSliceFrame } from '@nine-slice-frame/vue';
Your content here
```
#### Svelte
```svelte
import { NineSliceFrame } from '@nine-slice-frame/svelte';
Your content here
```
#### Solid
```tsx
import { NineSliceFrame } from '@nine-slice-frame/solid';
function App() {
return (
Your content here
);
}
```
### Props
| Prop | Type | Default | Description |
| ------------- | --------------------------------------------- | ----------- | --------------------------------------------------------------------------------- |
| `imagePath` | `string` | required | Path to the image (relative to public folder) |
| `slice` | `number \| object` | `8` | Slice values - number for uniform, or `{ top, right, bottom, left }` for per-edge |
| `borderWidth` | `number` | `5` | Visual border width in pixels |
| `repeat` | `'stretch' \| 'repeat' \| 'round' \| 'space'` | `'stretch'` | Border repeat mode |
| `fill` | `boolean` | `true` | Use 'fill' to show center of image as background |
| `pixelated` | `boolean` | `true` | Use pixelated rendering for pixel art |
| `className` | `string` | `''` | Additional CSS class names |
| `style` | `React.CSSProperties` | `{}` | Additional inline styles |
### Advanced: Different Slice Values Per Edge
```tsx
Content with asymmetric border
```
## Development
This is a monorepo managed with pnpm workspaces.
```bash
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Build React package only
pnpm build:react
# Run demo site locally
pnpm demo:serve
```
## Roadmap
- [x] React component
- [x] Vue component
- [x] Svelte component
- [x] Solid component
- [x] Interactive demo/tester tool
## Contributing
Contributions are welcome! Here's how you can help:
1. **Fork the repository** and create your branch from `main`
2. **Make your changes** in your forked repository
3. **Test your changes** - Run `pnpm build` and `pnpm test` to ensure everything works
4. **Submit a pull request** with a clear description of your changes
### Development Setup
```bash
# Clone the repository
git clone https://github.com/callum-gander/nine-slice-frame.git
cd nine-slice-frame
# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests
pnpm test
# Type checking
pnpm typecheck
```
### Reporting Issues
Found a bug or have a feature request? Please [open an issue](https://github.com/callum-gander/nine-slice-frame/issues) with:
- A clear description of the problem or suggestion
- Steps to reproduce (for bugs)
- Expected vs actual behavior
- Screenshots or code examples if applicable
## Resources
- 🎮 [Live Demo & Tester](https://callum-gander.github.io/nine-slice-frame/)
## License
MIT © Callum Gander