neu-design-system
v1.1.1
Published
Neubrutalism React component library. Black borders, hard drop shadows, pastel block colours.
Readme
neu-design-system
Neubrutalism React component library. Black 3px borders, 4px hard drop shadows, pastel block colours, 0px border-radius. Space Grotesk headings, Inter body.
Preview: https://jesseyay.github.io/neu-design-system/
Setup
npm (recommended)
npm install neu-design-systemimport 'neu-design-system/styles' // all component CSS + tokens
import { Button, Card, Input } from 'neu-design-system'Ships pre-built ESM + CJS + TypeScript declarations. React ≥18 required as a peer dep.
Git submodule
git submodule add https://github.com/jesseyay/neu-design-system.git src/neuUpdate: git submodule update --remote
import 'src/neu/src/styles/global.css'
import { Button, Card, Input } from 'src/neu/src/components'Requires the consuming bundler to handle TypeScript/JSX (Vite, Next.js, CRA all work).
npm local path
{ "dependencies": { "neu-design-system": "file:../neu-design-system" } }Components
| Component | Key props |
|-----------|-----------|
| Button | color size fullWidth disabled — extends <button> |
| Card | color hoverable header footer |
| Input | label hint error required — extends <input> |
| Textarea | label hint error required — extends <textarea> |
| Select | label options: {value,label}[] — extends <select> |
| Badge | color size |
| Alert | type: info\|success\|warning\|danger title |
| Checkbox | label checked defaultChecked disabled onChange(bool) |
| Toggle | label checked defaultChecked disabled onChange(bool) |
| RadioGroup | name options: {value,label,disabled?}[] value defaultValue direction onChange(val) |
| Slider | min max step value defaultValue color showValue valueSuffix onChange(num) |
| Accordion | items: {id,title,content}[] defaultOpen: string[] allowMultiple color |
| Modal | open onClose title footer |
color values (all components that accept it)
yellow pink mint blue lavender orange lime peach white black
size values (Button, Badge)
sm md lg
Design tokens (CSS custom properties)
/* Border */
--neu-border: 3px solid #000;
--neu-border-width: 3px;
--neu-border-radius: 0px;
/* Shadows — hard offset, zero blur */
--neu-shadow-xs: 2px 2px 0px #000;
--neu-shadow-sm: 3px 3px 0px #000;
--neu-shadow: 4px 4px 0px #000; /* default */
--neu-shadow-md: 5px 5px 0px #000;
--neu-shadow-lg: 8px 8px 0px #000;
--neu-shadow-xl: 12px 12px 0px #000;
/* Colours */
--neu-yellow: #FFEE45; --neu-pink: #FF90BB; --neu-mint: #A8F0C6;
--neu-blue: #7EC8E3; --neu-lavender: #C9B8FF; --neu-orange: #FFB347;
--neu-lime: #BFFF80; --neu-peach: #FFD4B8;
--neu-black: #000; --neu-white: #fff; --neu-bg: #FFFBF0;
/* Typography */
--neu-font-display: 'Space Grotesk', system-ui, sans-serif;
--neu-font-body: 'Inter', system-ui, sans-serif;To override tokens, redefine them in your own :root after importing tokens.css.
Usage examples
<Button color="yellow" size="lg">Buy now</Button>
<Card color="mint" header="Title" footer={<Button size="sm">Go</Button>}>
Body content
</Card>
<Input label="Email" type="email" required hint="Never shared" />
<RadioGroup
name="plan"
label="Plan"
defaultValue="pro"
options={[
{ value: 'free', label: 'Free' },
{ value: 'pro', label: 'Pro — $12/mo' },
]}
onChange={(val) => console.log(val)}
/>
<Slider label="Volume" defaultValue={70} valueSuffix="%" color="blue" />
<Accordion
defaultOpen={['q1']}
items={[
{ id: 'q1', title: 'Question', content: 'Answer.' },
]}
/>
<Modal open={open} onClose={() => setOpen(false)} title="Confirm">
Are you sure?
</Modal>