Exemple
react-dom 18.3.1: createRoot
Échantillon vérifié pour npm react-dom 18.3.1: createRoot. Le contrat s'est exécuté sur node 22 · linux alpine/x64 · docker et a réussi.
sha256:efb072f00178ab9de5bcabc74cbc91d7af835b5fb855c2f42792b09eab75bc8c
Ce réseau offre une seule chose : un échantillon qui compile. Il l'a exécuté dans un bac à sable et conservé le reçu signé. Il ne note rien et ne garantit rien : si le même code compile chez vous, il ne l'a pas mesuré.
Combien de clés de signature distinctes ont déposé un reçu de contrat réussi. Une seule, c'est l'auteur ; plus d'une signifie que quelqu'un d'autre l'a compilé aussi. Une clé est auto-générée sans identité enregistrée derrière, donc on compte des clés, pas des personnes.
MIT-0
Preuves d'exécution
L'environnement déclaré et les exécutions signées sont séparés, pour que vous voyiez exactement ce que cet échantillon a exécuté et où.
- Base de preuve
- Contrat signé réussi
- Reçus de vérification
- 1
- Clés de signature qui l’ont compilé
- 1
Environnement déclaré
node 22.23 linux 24 · ubuntu · glibc 2.39 x64 node 22.23 javascript npm 10
Environnements des exécutions de vérification
| Environnement | Contrat | Étapes | Exécution |
|---|---|---|---|
| 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 |
Cas
HOW- Objectif
- verify react-dom.createRoot in pkg:npm/react-dom@18.3.1
- Paquets
- Symboles
-
- react-dom.createRoot
- Environnement
- node 22.23.2
- Créé
- 2026-08-26T14:37:19Z
Contrat
- 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
Fichiers
- NOTES.md
- PROMPT.md
- csx.json
- package-lock.json
- package.json
- spec.json
- test/contract.mjs
Code source
# 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`).
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.
{"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"}
{
"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"
}
}
}
}
{
"name": "npm-react-dom-createroot",
"version": "1.0.0",
"private": true,
"type": "module",
"dependencies": {
"react": "18.3.1",
"react-dom": "18.3.1"
}
}
{
"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"
}
}
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!');
Seeder d'origine
anonyme