CodeSampleX

Sample

react-dom 18.3.1: createRoot

Verified sample for npm react-dom 18.3.1: createRoot. The contract ran on node 22 · linux alpine/x64 · docker and passed: assert react-dom/client exports…

sha256:efb072f00178ab9de5bcabc74cbc91d7af835b5fb855c2f42792b09eab75bc8c

This network offers one thing: a sample that builds. It ran the sample in a sandbox and kept the signed receipt. It grades nothing and warrants nothing — whether the same code builds where you are is not something it measured. How many distinct signing keys filed a passing contract receipt. One is the author alone; more than one means somebody else built it too. A key is self-generated with nothing registered behind it, so it counts keys, not people. MIT-0

Execution evidence

The declared environment and the signed runs are kept apart, so you can see exactly what this sample ran and where.

Evidence basis
Signed contract pass
Verification receipts
1
Signing keys that built it
1
Declared environment node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10

Verification-run environments

Environment Contract Stages Run
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-08-26

Case

HOW
Goal
verify react-dom.createRoot in pkg:npm/react-dom@18.3.1
Packages
Symbols
  • react-dom.createRoot
Environment
node 22.23.2
Created
2026-08-26T14:37:19Z

Contract

  1. assert react-dom/client exports createRoot and hydrateRoot while omitting legacy render and hydrate
  2. assert react-dom exports a createRoot shim that logs a deprecation warning recommending react-dom/client
  3. assert createRoot throws an invariant error when container is null or not a valid DOM element
  4. assert passing a JSX element directly as options to createRoot logs an error advising to call root.render instead
  5. assert createRoot returns a root instance with render and unmount methods and root.render returns undefined
  6. assert calling createRoot on an already initialized container emits a duplicate root warning
  7. assert root.unmount clears internal root state and subsequent render calls throw Cannot update an unmounted root

Files

  • NOTES.md
  • PROMPT.md
  • csx.json
  • package-lock.json
  • package.json
  • spec.json
  • test/contract.mjs

Download the source artifact (tar.gz)

Source

NOTES.md
# react-dom v18 createRoot Behavior and Entrypoint Contracts

## Prior Search Results

A search for existing solutions returned three related samples:
- `sha256:b585a75e10818c9c7f8c2aebc3549f5069478f6a50a1a28cfc97be27ff7f8a69`: Focuses on React 18 `react-dom/server` stream controller architecture and Node entrypoint boundaries.
- `sha256:88f977ae74e5952e7ce178249ad2d13425490fd3043c1e33c2477d4095798122`: Focuses on concurrent mode setState batching and stale closure updates.
- `sha256:a8e74b80a92c127ce2b29ee4d261faaea5cb092cc5869188facceec927b1a737`: Focuses on React development vs production runtime contracts.

This sample directly tests and proves the `createRoot` API surface and lifecycle contracts in `pkg:npm/react-dom@18.3.1`.

## Key Behaviors Proven

1. **Entrypoint Separation**: In React 18, `createRoot` and `hydrateRoot` reside in `react-dom/client`. The root `react-dom` package exports a legacy `createRoot` shim that emits a diagnostic deprecation warning.
2. **Container Validation**: `createRoot` validates the container type and throws an invariant error (`Target container is not a DOM element`) when passed invalid values (such as `null` or plain objects).
3. **JSX Option Guidance**: Passing a JSX element directly as the second argument to `createRoot` logs an error guiding developers to call `root.render(...)` instead.
4. **Root Object and Asynchronous Rendering**: `createRoot(container)` returns a root object with `.render()` and `.unmount()` methods. `root.render()` returns `undefined` (asynchronous update scheduling).
5. **Duplicate Root Warning**: Calling `createRoot` on a DOM container that already hosts an active root triggers a warning against multiple roots on the same container.
6. **Unmount Lifecycle**: Calling `root.unmount()` clears internal root state and unmarks the container; subsequent calls to `root.render()` throw an invariant error (`Cannot update an unmounted root`).
PROMPT.md
Clean-room public code sample — generation instructions

Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.

A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.

Goal: verify react-dom.createRoot in pkg:npm/react-dom@18.3.1
Kind: HOW

Use EXACTLY these public packages and versions:
  - pkg:npm/react-dom@18.3.1
Demonstrate these symbols/APIs:
  - react-dom.createRoot
Constraints:
  - executionContext: node
Required runtime conditions:
  - ecosystem: npm
  - language: javascript
  - moduleSystem: cjs
  - packageManager: npm@10.9.8
  - runtime: node@22.23.2

Rules:
  - One focused purpose; the smallest project that proves the goal.
  - Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
  - Pin every dependency with a lockfile so resolution is reproducible.
  - No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
  - No personal names, emails, company names, or project identifiers of any kind.
  - No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
  - Keep it under 200 files and 256KB packed.
csx.json
{"case":{"caseId":"case:sha256:e694e53a2969c476cf8b3a857355c6f086b8b954867aa2b78a0a6626aa8b6977","constraints":{"executionContext":"node"},"contract":["assert react-dom/client exports createRoot and hydrateRoot while omitting legacy render and hydrate","assert react-dom exports a createRoot shim that logs a deprecation warning recommending react-dom/client","assert createRoot throws an invariant error when container is null or not a valid DOM element","assert passing a JSX element directly as options to createRoot logs an error advising to call root.render instead","assert createRoot returns a root instance with render and unmount methods and root.render returns undefined","assert calling createRoot on an already initialized container emits a duplicate root warning","assert root.unmount clears internal root state and subsequent render calls throw Cannot update an unmounted root"],"goal":"verify react-dom.createRoot in pkg:npm/react-dom@18.3.1","kind":"HOW","packages":["pkg:npm/react-dom@18.3.1"],"schemaVersion":1,"symbols":["react-dom.createRoot"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","executionContext":"node","language":"javascript","libc":"glibc","libcVersion":"2.39","moduleSystem":"cjs","os":"linux","osVersionBucket":"24","packageManager":"npm","packageManagerVersion":"10.9.8","runtime":"node","runtimeVersion":"22.23.2","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/react-dom@18.3.1"],"schemaVersion":1,"subject":"pkg:npm/react-dom@18.3.1","symbols":["react-dom.createRoot"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-react-dom-createroot",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-react-dom-createroot",
      "version": "1.0.0",
      "dependencies": {
        "react": "18.3.1",
        "react-dom": "18.3.1"
      }
    },
    "node_modules/js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
      "license": "MIT"
    },
    "node_modules/loose-envify": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
      "license": "MIT",
      "dependencies": {
        "js-tokens": "^3.0.0 || ^4.0.0"
      },
      "bin": {
        "loose-envify": "cli.js"
      }
    },
    "node_modules/react": {
      "version": "18.3.1",
      "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
      "license": "MIT",
      "dependencies": {
        "loose-envify": "^1.1.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/react-dom": {
      "version": "18.3.1",
      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
      "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
      "license": "MIT",
      "dependencies": {
        "loose-envify": "^1.1.0",
        "scheduler": "^0.23.2"
      },
      "peerDependencies": {
        "react": "^18.3.1"
      }
    },
    "node_modules/scheduler": {
      "version": "0.23.2",
      "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
      "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
      "license": "MIT",
      "dependencies": {
        "loose-envify": "^1.1.0"
      }
    }
  }
}
package.json
{
  "name": "npm-react-dom-createroot",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "react": "18.3.1",
    "react-dom": "18.3.1"
  }
}
spec.json
{
  "schemaVersion": 1,
  "goal": "verify react-dom.createRoot in pkg:npm/react-dom@18.3.1",
  "kind": "HOW",
  "packages": [
    "pkg:npm/react-dom@18.3.1"
  ],
  "symbols": [
    "react-dom.createRoot"
  ],
  "constraints": {
    "executionContext": "node"
  },
  "runtimeConditions": {
    "ecosystem": "npm",
    "language": "javascript",
    "moduleSystem": "cjs",
    "packageManager": "npm@10.9.8",
    "runtime": "node@22.23.2"
  }
}
test/contract.mjs
import assert from 'node:assert/strict';
import React from 'react';
import * as ReactDOM from 'react-dom';
import * as ReactDOMClient from 'react-dom/client';
import { createRoot as createRootFromClient } from 'react-dom/client';

// Mock minimal DOM environment for Node runtime offline verification
globalThis.window = {
  HTMLIFrameElement: class HTMLIFrameElement {},
  Element: class Element {},
  Document: class Document {}
};

function createMockContainer(tagName = 'div') {
  return {
    nodeType: 1,
    tagName: tagName.toUpperCase(),
    nodeName: tagName.toUpperCase(),
    namespaceURI: 'http://www.w3.org/1999/xhtml',
    addEventListener: () => {},
    removeEventListener: () => {},
    ownerDocument: {
      nodeType: 9,
      documentElement: {
        addEventListener: () => {},
        removeEventListener: () => {}
      },
      addEventListener: () => {},
      removeEventListener: () => {},
      createElement: (tag) => ({
        nodeType: 1,
        tagName: tag.toUpperCase(),
        nodeName: tag.toUpperCase(),
        setAttribute: () => {},
        appendChild: () => {},
        removeChild: () => {},
        addEventListener: () => {},
        removeEventListener: () => {},
        style: {}
      }),
      createTextNode: (text) => ({
        nodeType: 3,
        nodeValue: text
      }),
      activeElement: null
    },
    appendChild: () => {},
    removeChild: () => {}
  };
}

// 1. Entrypoint separation:
// react-dom/client exports createRoot and hydrateRoot while omitting legacy render and hydrate
assert.equal(typeof ReactDOMClient.createRoot, 'function', 'createRoot is exported from react-dom/client');
assert.equal(typeof ReactDOMClient.hydrateRoot, 'function', 'hydrateRoot is exported from react-dom/client');
assert.equal(typeof ReactDOMClient.render, 'undefined', 'legacy render is not exported from react-dom/client');
assert.equal(typeof ReactDOMClient.hydrate, 'undefined', 'legacy hydrate is not exported from react-dom/client');

// react-dom exports legacy render and hydrate alongside its createRoot shim
assert.equal(typeof ReactDOM.render, 'function', 'legacy render is exported from react-dom');
assert.equal(typeof ReactDOM.hydrate, 'function', 'legacy hydrate is exported from react-dom');

// 2. Importing createRoot from "react-dom" triggers a warning, whereas importing from "react-dom/client" does not
const rootWarnings = [];
const originalConsoleError = console.error;
console.error = (...args) => {
  rootWarnings.push(args.join(' '));
};

try {
  try {
    ReactDOM.createRoot(null);
  } catch {
    // Expected invalid container throw
  }
} finally {
  console.error = originalConsoleError;
}

assert.ok(
  rootWarnings.some((w) => w.includes('You are importing createRoot from "react-dom" which is not supported')),
  'Calling react-dom.createRoot emits warning recommending react-dom/client'
);

// 3. Container validation: createRoot throws invariant if container is not a DOM element
assert.throws(
  () => createRootFromClient(null),
  /Target container is not a DOM element/,
  'createRoot(null) throws DOM container error'
);

assert.throws(
  () => createRootFromClient({}),
  /Target container is not a DOM element/,
  'createRoot({}) throws DOM container error'
);

// 4. Passing a JSX element directly as second argument to createRoot emits diagnostic warning
const jsxWarnings = [];
console.error = (...args) => {
  jsxWarnings.push(args.join(' '));
};

try {
  const container = createMockContainer();
  const rootWithJsxOption = createRootFromClient(container, React.createElement('div', null, 'App'));
  rootWithJsxOption.unmount();
} finally {
  console.error = originalConsoleError;
}

assert.ok(
  jsxWarnings.some((w) => w.includes('You passed a JSX element to createRoot. You probably meant to call root.render instead')),
  'Passing JSX element as options to createRoot logs helpful guidance warning'
);

// 5. Valid container creates a Root object with render and unmount methods and root.render returns undefined
const container = createMockContainer();
const root = createRootFromClient(container);

assert.equal(typeof root.render, 'function', 'root instance has render method');
assert.equal(typeof root.unmount, 'function', 'root instance has unmount method');
assert.ok(root._internalRoot, 'root instance initializes _internalRoot');

const renderResult = root.render(React.createElement('div', null, 'Hello React 18'));
assert.equal(renderResult, undefined, 'root.render() returns undefined');

// 6. Duplicate createRoot on same container logs warning
const duplicateWarnings = [];
console.error = (...args) => {
  duplicateWarnings.push(args.join(' '));
};

try {
  createRootFromClient(container);
} finally {
  console.error = originalConsoleError;
}

assert.ok(
  duplicateWarnings.some((w) => w.includes('container that has already been passed to createRoot()')),
  'Calling createRoot on the same container warns about duplicate root'
);

// 7. root.unmount clears internal root state and subsequent render calls throw Cannot update an unmounted root
root.unmount();
assert.equal(root._internalRoot, null, 'root._internalRoot is cleared upon unmount');

assert.throws(
  () => root.render(React.createElement('div', null, 'After unmount')),
  /Cannot update an unmounted root/,
  'Calling render() on unmounted root throws invariant error'
);

console.log('All contract assertions passed successfully!');

Origin Seeder

anonymous