style-to-object
Parses CSS inline style strings into plain JavaScript objects, powering markdown-to-jsx, react-markdown, and dozens of other rendering pipelines.
Repository Health
Technical Analysis
style-to-object is a single-purpose TypeScript library that converts a CSS inline style string (as found in an HTML style attribute) into a plain JavaScript object of property/value pairs. It builds on the same author’s inline-style-parser for tokenizing declarations, then reduces the parsed declarations into either a flat object or, when an iterator callback is supplied, a per-declaration (and per-comment) stream that callers can use to build any custom output shape.
With tens of millions of weekly downloads, it functions as foundational plumbing for the Markdown/JSX rendering ecosystem — most notably markdown-to-jsx and the react-markdown/rehype/hast toolchain, which use it to turn raw inline style="..." strings from parsed HTML/Markdown into React-compatible style objects. It ships dual ESM and CommonJS builds with full TypeScript declarations and has no runtime dependencies beyond inline-style-parser.
What You Get
- A single default export,
StyleToObject(style, iterator?), with zero configuration required - Parses multi-declaration inline style strings into a flat
{ property: value }object - Optional iterator callback (
(property, value, declaration) => void) for custom output shapes instead of the default object - Iterator mode also surfaces CSS comments as declaration-like nodes, not just property/value pairs
- Well-defined
nullvs throw semantics: invalid/empty/non-string input returnsnull; malformed CSS (e.g. an unterminated comment) throws - Dual ESM (
esm/) and CommonJS (cjs/) builds with generated.d.ts/.d.mtstype declarations and a correctexportsmap - Zero runtime dependencies besides
inline-style-parserfrom the same maintainer
Common Use Cases
- Converting an HTML element’s inline
style="..."attribute into a React-compatiblestyleobject when rendering parsed Markdown or HTML (asmarkdown-to-jsxandreact-markdown/rehypeplugins do) - Building custom CSS-declaration processors via the iterator API — e.g. collecting
[property, value]tuples, filtering specific properties, or transforming values before use - Normalizing inline styles scraped or extracted from third-party HTML into a serializable JS object for storage, diffing, or SSR hydration
- Validating or linting inline style strings by relying on the library’s throw-on-malformed-CSS behavior
- Powering browser-side tools/playgrounds (as shown in the project’s own bundled example) that live-parse a style string typed by a user
Under The Hood
Architecture
The entire library is one file (src/index.ts) exporting a single default function, StyleToObject, that delegates CSS tokenizing/parsing to the same author’s inline-style-parser package and then reduces its Declaration[] output into a result: either accumulating into a flat StyleObject record when no iterator is passed, or invoking the caller’s iterator once per declaration (including comment nodes) when one is. There is no internal state, class, or plugin surface — the whole “layer” is a guard clause plus a single forEach with a branch, which is an appropriately minimal design for the library’s narrow, well-defined scope.
Tech Stack
Written in TypeScript and built with tsdown (an oxc/Rollup-based bundler) into dual CJS and ESM outputs matching the package.json exports map, with generated .d.ts/.d.mts declaration files for both. The sole runtime dependency is inline-style-parser. Dev tooling includes ESLint 10 with strict, type-checked typescript-eslint configs, Prettier, Husky + lint-staged pre-commit hooks, commitlint with conventional-commit enforcement, Jest 30 with ts-jest for tests, and publint for verifying the package’s export map before publish. CI runs on GitHub Actions with Codecov coverage reporting, and releases are fully automated via Release Please.
Code Quality
Tests live in __tests__/index.test.ts (plus a compiled .mjs variant exercised via a dedicated test:esm script) and are driven by shared fixture tables covering valid parses, inputs that must throw, inputs that must return null, and the iterator’s comment-handling path — each behavior is explicitly enumerated rather than left implicit. Error handling is intentionally simple: malformed CSS throws by letting errors from inline-style-parser propagate, while invalid/empty/non-string input is checked upfront and returns null. The codebase is fully typed under strict TypeScript (enforced via a dedicated tsc pre-publish check), and linting/formatting are enforced pre-commit. For its size, the project has thorough, deliberately-documented test coverage and consistent tooling.
API Design
The public surface is a single default export taking a style string plus an optional iterator — no config object or setup step. The iterator signature (property, value, declaration) mirrors familiar array-iteration ergonomics, letting callers either take the default flattened object or fully customize the output shape (as the README itself demonstrates by building an array of tuples). Return semantics are deliberately simple and total — invalid input always yields null rather than throwing, and this contract is exhaustively covered by both docs and tests, so consumers can rely on documented behavior rather than probing edge cases themselves. Combined with dual ESM/CJS builds and full type declarations, it’s about as low-friction a DX as a narrowly-scoped utility library can offer.
Used by 2 apps in this directory
Kener
Monitoring · Devops
Stunning, self-hosted status pages with real-time uptime monitoring, incident management, and multi-channel notifications in a single Docker container.
Windmill
Automation · Developer Tools
Turn scripts into webhooks, workflows, and auto-generated UIs — the fastest self-hostable workflow engine, 13x faster than Airflow.