react-base16-styling
react-base16-styling is a small theming and prop-generation utility used by Redux DevTools components. You provide a function that maps a Base16 palette to named styles, then ask the returned styling function for one or more names and spread its { className, style } result onto an element. It includes built-in Base16 palettes, theme inversion, custom class and inline-style overrides, and dynamic style functions. Despite the name, version 0.10.0 does not depend on React; it produces props that happen to fit React elements.
A practical compatibility choice for Redux DevTools-style interfaces already committed to Base16 palettes. New application design systems should choose semantic tokens and a maintained styling layer with React integration and real CSS output.
Use it if
- You are maintaining Redux DevTools-adjacent UI that already represents themes as Base16 base00 through base0F palettes
- You need one theme entry to combine class names, inline style objects, and functions that receive component state
- You want consumers to override named component styles without replacing the entire default theme
- You need the package's built-in Base16 themes and light/dark inversion helper in an ESM TypeScript project
- You are starting a general application design system: the API is built around the 16-color Base16 convention, not semantic tokens such as surface, danger, spacing, typography, or breakpoints
- You need a React provider, context, hooks, server rendering support, or generated CSS: the package only returns className and inline style props and has no React dependency
- Your toolchain still uses CommonJS require: version 0.10.0 declares type: module and exposes only ./lib/index.js, and its changelog calls the ESM conversion a minor change
- You require a stable post-1.0 contract: the package remains at 0.10.0, and the changelog records a breaking helper rename in 0.7.0 before the later ESM conversion
- You want CSS features inline styles cannot express, including pseudo-selectors, media queries, keyframes, and automatic vendor processing; string values can add classes, but this package does not create the corresponding CSS
Setup reality
Installation is one package, but version 0.10.0 is ESM-only: use import, not require, and make sure the consuming build handles ES modules. There is no React peer dependency because the output is simply an object containing className and style. The real setup is designing a getStylingFromBase16 function whose keys become your component's styling contract. Every Base16 palette is expected to contain scheme, author, and base00 through base0F values. createStyling is curried: give it the palette-to-styles function and options first, then supply a theme or override object, then request named keys. That extra stage is easy to omit. Named styles may be strings, inline-style objects, or functions returning { className, style }; functions receive the accumulated result plus any extra arguments passed at lookup time. Multiple keys merge left to right. Custom class names append, while later style properties overwrite earlier ones. Theme strings can name a bundled palette or one supplied through base16Themes, and the :inverted suffix requests generated inverse colors. An unknown string is not safely ignored when inverted, so validate user-controlled theme names before appending that suffix. Inline styles still cannot express selectors, media rules, or keyframes, and the package does not ship a provider, persistence layer, CSS reset, or component library. TypeScript declarations are included, but dynamic callback arguments are typed as unknown, so component-specific casts or wrapper types are often needed.
Patterns
Install and import the ESM packageinstall-and-import
npm install react-base16-styling
import {
createStyling,
base16Themes,
invertTheme,
} from 'react-base16-styling';Version 0.10.0 is an ESM package with a single export path. CommonJS require is not part of the published package contract.
Map a Base16 palette to named stylesdefine-style-contract
import { createStyling } from 'react-base16-styling';
const getStyles = (theme) => ({
panel: {
color: theme.base05,
backgroundColor: theme.base00,
border: `1px solid ${theme.base02}`,
},
heading: { color: theme.base0D },
});
const withTheme = createStyling(getStyles);The object keys are your component's public styling contract. Base16 colors are generic slots, so document what each slot means in your UI.
Create props with the default paletteapply-default-theme
const styling = withTheme();
export function Panel({ children }) {
return <section {...styling('panel')}>{children}</section>;
}createStyling returns a theme-selection function first. Call that function before requesting a named style.
Select one of the bundled Base16 themesselect-builtin-theme
const withNamedThemes = createStyling(getStyles, {
defaultBase16: base16Themes.default,
});
const solarizedProps = withNamedThemes('solarized')('panel');Names are resolved against bundled themes unless you supply a base16Themes map in the options. Validate user-supplied names because an unknown name does not produce a useful theme.
Use a complete custom Base16 palettesupply-custom-theme
const ocean = {
scheme: 'Ocean', author: 'Your team',
base00: '#1b2b34', base01: '#343d46', base02: '#4f5b66', base03: '#65737e',
base04: '#a7adba', base05: '#c0c5ce', base06: '#cdd3de', base07: '#d8dee9',
base08: '#ec5f67', base09: '#f99157', base0A: '#fac863', base0B: '#99c794',
base0C: '#5fb3b3', base0D: '#6699cc', base0E: '#c594c5', base0F: '#ab7967',
};
const styling = withTheme(ocean);Provide every base00 through base0F entry. Missing slots fall back to the package default palette, which can silently mix two schemes.
Merge several named stylescombine-style-keys
const styling = withTheme('apathy');
const props = styling(['panel', isSelected && 'selected', isDisabled && 'disabled']);
return <button {...props}>Save</button>;False and undefined keys are ignored. Styles merge left to right, so properties from later keys win when they target the same CSS property.
Compute a style from component stateadd-dynamic-style
const getStyles = (theme) => ({
meter: ({ style }, value) => ({
style: {
...style,
width: `${Math.max(0, Math.min(100, value))}%`,
backgroundColor: theme.base0B,
},
}),
});
const styling = createStyling(getStyles)();
return <div {...styling('meter', percent)} />;Extra lookup arguments are passed to style functions. In the bundled TypeScript types those arguments are unknown, so type them in a local wrapper when possible.
Return class names and inline styles togethermix-class-and-style
const getStyles = (theme) => ({
button: ({ className, style }) => ({
className: [className, 'toolbar-button'].filter(Boolean).join(' '),
style: { ...style, color: theme.base05 },
}),
});
const styling = createStyling(getStyles)();
return <button {...styling('button')}>Run</button>;The helper does not generate CSS for class names. The toolbar-button rule must come from your own stylesheet or another styling system.
Let a consumer override named stylesoverride-component-styles
const createPanelStyling = createStyling(getStyles, {
defaultBase16: base16Themes.apathy,
});
const styling = createPanelStyling({
panel: { borderRadius: 8 },
heading: 'product-heading',
});Object properties are merged over defaults, while class strings append to default class names. This is composition, not complete replacement.
Extend a named palette with component overridesextend-named-theme
const styling = createStyling(getStyles, {
base16Themes: { ocean },
})({
extend: 'ocean',
panel: { padding: 16 },
heading: 'compact-heading',
});extend chooses the base palette; every other non-Base16 key is treated as a custom named style and merged with the defaults.
Create an inverted theme selectioninvert-theme
import { createStyling, invertTheme } from 'react-base16-styling';
const selectedTheme = invertTheme('apathy'); // 'apathy:inverted'
const styling = createStyling(getStyles)(selectedTheme);Inversion transforms Base16 colors in YUV space; it is not a hand-tuned accessible light theme. Check contrast for your actual text and controls.
Resolve or invert a palette directlyinspect-base16-theme
import {
getBase16Theme,
invertBase16Theme,
base16Themes,
} from 'react-base16-styling';
const apathy = getBase16Theme('apathy');
const lightApathy = invertBase16Theme(base16Themes.apathy);getBase16Theme can return undefined for objects without base00. Guard the result before passing it to code that expects a complete Base16Theme.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| styled-components | npm | You want React context theming plus generated CSS, selectors, media queries, and component-scoped styles |
| @emotion/react | npm | You want a theme provider and CSS-in-JS with object or template syntax in a modern React app |
| theme-ui | npm | You want a token-based design system with variants and a theme-aware sx prop |
| base16 | npm | You only need Base16 scheme data and do not need this package's React-shaped style merging |