{"id":13081,"library":"dom-chef","title":"Build DOM Elements with JSX","description":"dom-chef is a lightweight library that enables developers to construct native browser DOM elements using JSX syntax, bypassing the need for unsafe `innerHTML` or verbose `document.createElement` calls. It acts as a JSX compiler target, transforming JSX into direct DOM API calls without introducing a virtual DOM layer, offering a performant and small-footprint alternative to larger frameworks. The current stable version is 5.1.1, with a consistent release cadence addressing features and stability. Key differentiators include its direct DOM manipulation approach, comprehensive support for SVG, event listeners, inline styles, nested elements, and functional components, all while shipping TypeScript types for a robust developer experience. It is not a full UI framework but a utility for DOM construction.","status":"active","version":"5.1.1","language":"javascript","source_language":"en","source_url":"https://github.com/vadimdemedes/dom-chef","tags":["javascript","jsx","dom","native","innerHTML","document","createElement","create","element","typescript"],"install":[{"cmd":"npm install dom-chef","lang":"bash","label":"npm"},{"cmd":"yarn add dom-chef","lang":"bash","label":"yarn"},{"cmd":"pnpm add dom-chef","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides a list of known SVG tag names for correct element creation.","package":"svg-tag-names","optional":false}],"imports":[{"note":"The primary JSX factory function. Required configuration in `tsconfig.json` or `babel.config.js` for `jsxFactory`.","wrong":"const h = require('dom-chef');","symbol":"h","correct":"import { h } from 'dom-chef';"},{"note":"An alternative import for JSX transpilers configured to default to `React.createElement`. This allows `dom-chef` to function as the `React` object. It's a default export from `dom-chef`.","wrong":"import { React } from 'dom-chef';","symbol":"React","correct":"import React from 'dom-chef';"},{"note":"Not a direct import, but the native `DocumentFragment` constructor is used as the `jsxFragmentFactory`. Ensure your JSX transpiler is configured to use it, rather than importing it.","wrong":"import { DocumentFragment } from 'dom-chef';","symbol":"DocumentFragment","correct":"/** Configure jsxFragmentFactory: */\n// tsconfig.json: {\"compilerOptions\": {\"jsxFragmentFactory\": \"DocumentFragment\"}}"}],"quickstart":{"code":"import {h} from 'dom-chef';\n\n// A simple function component\nfunction Greeting({name, theme}: {name: string; theme: string}): HTMLElement {\n  return (\n    <h2 className={`greeting-${theme}`}>Hello, {name}!</h2>\n  );\n}\n\nconst handleClick = (e: MouseEvent) => {\n  const button = e.target as HTMLButtonElement;\n  button.textContent = 'Clicked!';\n  console.log('Button clicked!', button);\n};\n\n// Create a complex DOM structure using JSX\nconst appContainer = (\n  <div className=\"app-root\">\n    <h1>Welcome to dom-chef example!</h1>\n    <Greeting name=\"World\" theme=\"dark\" />\n    <section>\n      <p>This paragraph uses inline <strong style={{color: 'blue'}}>styles</strong>.</p>\n      <button onClick={handleClick}>Click me</button>\n      <input type=\"text\" placeholder=\"Type something...\" onInput={(e) => console.log((e.target as HTMLInputElement).value)} />\n    </section>\n    <div dangerouslySetInnerHTML={{__html: '<em>This HTML is rendered dangerously.</em>'}} />\n    <svg width={100} height={100}>\n      <circle cx={50} cy={50} r={40} stroke=\"green\" strokeWidth={4} fill=\"yellow\" />\n    </svg>\n  </div>\n);\n\n// Append the created element to the document body\ndocument.body.appendChild(appContainer);\n\n// Example of accessing a created element\nconst heading = appContainer.querySelector('h1');\nif (heading) {\n  console.log('Heading text:', heading.textContent);\n}\n\n// To compile this, ensure your build tool (e.g., TypeScript, Babel, esbuild) is configured for JSX.\n// For TypeScript, in your tsconfig.json:\n// {\"compilerOptions\": {\"jsx\": \"react\", \"jsxFactory\": \"h\", \"jsxFragmentFactory\": \"DocumentFragment\"}}","lang":"typescript","description":"Demonstrates creating a dynamic DOM structure, including functional components, event listeners, inline styles, and SVG elements using `dom-chef`'s JSX transformation."},"warnings":[{"fix":"Migrate your project to ES Modules, use a bundler (like webpack or Rollup) that supports ESM, or configure Node.js with '\"type\": \"module\"' in your package.json. If using TypeScript, ensure your 'module' compiler option is set appropriately (e.g., 'esnext').","message":"dom-chef v4.0.0 and above are exclusively exported as ES Modules (ESM). This removes CommonJS (CJS) support, requiring projects to adopt ESM or use a bundler capable of handling ESM imports.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Remove any custom `JSX` declarations from your `globals.d.ts` or other declaration files, as they may now conflict with the types provided by `dom-chef`.","message":"For TypeScript users, v5.0.0 introduced built-in TypeScript types for JSX. This means you likely no longer need to specify any `JSX` types in your `globals.d.ts` file.","severity":"breaking","affected_versions":">=5.0.0"},{"fix":"Avoid using the listed unsupported HTML tags directly within SVG JSX structures. If you need to embed such content, consider alternative rendering strategies or placing them outside the SVG context.","message":"When rendering SVG elements, certain HTML tags are explicitly unsupported due to the library's underlying DOM creation mechanism. Specifically, `<a>`, `<audio>`, `<canvas>`, `<iframe>`, `<script>`, and `<video>` tags cannot be nested inside an `<svg>` element.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Always sanitize any user-generated or external HTML content before assigning it via `dangerouslySetInnerHTML`. Prefer creating DOM elements programmatically or using text content where possible to avoid this risk.","message":"Using `dangerouslySetInnerHTML` can expose your application to cross-site scripting (XSS) attacks if the content is not sanitized. Only use this attribute with trusted HTML content.","severity":"gotcha","affected_versions":">=3.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"For TypeScript: Add `\"jsx\": \"react\", \"jsxFactory\": \"h\", \"jsxFragmentFactory\": \"DocumentFragment\"` to your `tsconfig.json` compiler options. For Babel: Configure `@babel/plugin-transform-react-jsx` with `pragma: 'h'` and `pragmaFrag: 'DocumentFragment'`.","cause":"The JSX transpiler (Babel, TypeScript, esbuild) is not configured to use 'h' as the JSX factory function, or JSX transformation is not enabled.","error":"ReferenceError: h is not defined"},{"fix":"Ensure your bundler is correctly configured to handle ESM modules and their default exports. For Webpack, this might involve ensuring correct `experiments.outputModule` or `resolve.fullySpecified` settings, or explicitly importing named exports if `h` is preferred.","cause":"Webpack or another bundler is attempting to `require` a default export from `dom-chef` (e.g., `import React from 'dom-chef'`) in a CommonJS context, which can cause interop issues after v4.0.0's ESM-only change.","error":"TypeError: __webpack_require__(...).default is not a function"},{"fix":"If using dom-chef < v5.0.0, ensure you have a `globals.d.ts` file with appropriate JSX type definitions (e.g., `interface IntrinsicElements { [elemName: string]: any; }`). If using dom-chef >= v5.0.0, remove any custom `JSX.IntrinsicElements` declarations that might be conflicting with the package's bundled types.","cause":"Before v5.0.0, TypeScript users needed custom JSX type declarations. After v5.0.0, conflicting or missing type declarations can cause this if `dom-chef`'s types aren't correctly picked up.","error":"Property 'className' does not exist on type 'IntrinsicElements...' (TypeScript error)"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":null,"cli_name":""}