{"id":21659137,"url":"https://github.com/Workiva/react-dart","last_synced_at":"2025-07-17T22:31:26.833Z","repository":{"id":11269397,"uuid":"13674420","full_name":"Workiva/react-dart","owner":"Workiva","description":"Dart Bindings for React JS","archived":false,"fork":false,"pushed_at":"2024-11-04T01:43:53.000Z","size":24075,"stargazers_count":413,"open_issues_count":23,"forks_count":67,"subscribers_count":39,"default_branch":"master","last_synced_at":"2024-11-15T05:54:25.639Z","etag":null,"topics":["dart","dart-wrapper","javascript","react-js","reactjs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Workiva.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-10-18T09:40:45.000Z","updated_at":"2024-11-04T01:43:56.000Z","dependencies_parsed_at":"2023-01-13T16:25:07.772Z","dependency_job_id":"24b6878b-0158-421c-9ba2-6fb57d87058c","html_url":"https://github.com/Workiva/react-dart","commit_stats":{"total_commits":1675,"total_committers":52,"mean_commits":32.21153846153846,"dds":0.7295522388059701,"last_synced_commit":"81a24b06b322fd7dfd89acf47509e4d7b9421b56"},"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Workiva%2Freact-dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Workiva%2Freact-dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Workiva%2Freact-dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Workiva%2Freact-dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Workiva","download_url":"https://codeload.github.com/Workiva/react-dart/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226305592,"owners_count":17603845,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dart-wrapper","javascript","react-js","reactjs"],"created_at":"2024-11-25T09:30:32.591Z","updated_at":"2025-07-17T22:31:26.828Z","avatar_url":"https://github.com/Workiva.png","language":"JavaScript","readme":"# Dart wrapper for [React JS](https://reactjs.org/)\n\n[![Pub](https://img.shields.io/pub/v/react.svg)](https://pub.dev/packages/react)\n![ReactJS v18.2.0](https://img.shields.io/badge/React_JS-18.2.0-green.svg)\n[![Dart CI](https://github.com/Workiva/react-dart/workflows/Dart%20CI/badge.svg?branch=master)](https://github.com/Workiva/react-dart/actions?query=workflow%3A%22Dart+CI%22+branch%3Amaster)\n[![React Dart API Docs](https://img.shields.io/badge/api_docs-react-blue.svg)](https://pub.dev/documentation/react/latest/)\n\n_Thanks to the folks at [Vacuumlabs](https://www.vacuumlabs.com/) for creating this project! :heart:_\n\n## Getting Started\n\n### Installation\n\nIf you are not familiar with the ReactJS library, read this [react tutorial](https://reactjs.org/docs/getting-started.html) first.\n\n1. Install the Dart SDK\n\n    ```bash\n    brew install dart\n    ```\n\n2. Create a `pubspec.yaml` file in the root of your project, and add `react` as a dependency:\n\n    ```yaml\n    name: your_package_name\n    version: 1.0.0\n    environment:\n      sdk: ^2.11.0\n    dependencies:\n      react: ^6.0.0\n    ```\n\n3. Install the dependencies using pub:\n\n    ```bash\n    dart pub get\n    ```\n\n### Wire things up\n\n#### HTML\n\nIn a `.html` file, include the javascript libraries\n_(provided with this library for compatibility reasons)_ within your `.html` file,\nand also add an element with an `id` to mount your React component.\n\nThis package now supports both React 17 and React 18. To opt into React 18, replace usages of this package's JS files with their new, React 18 versions (see table below).\n\nThe React 17 JS files are now deprecated, and will be removed in the next major version of this package, 8.0.0.\n\n##### React 18\n| Mode        | Library          | JS File Name                                |\n|-------------|------------------|---------------------------------------------|\n| Development | React \u0026 ReactDOM | packages/react/js/react.dev.js              |\n| Production  | React \u0026 ReactDOM | packages/react/js/react.min.js              |\n\n##### React 17 (Deprecated)\n| Mode        | Library          | JS File Name                                |\n|-------------|------------------|---------------------------------------------|\n| Development | React            | packages/react/react.js                     |\n| Development | ReactDOM         | packages/react/react_dom.js                 |\n| Production  | React \u0026 ReactDOM | packages/react/react_with_react_dom_prod.js |\n| Production  | React            | packages/react/react_prod.js                |\n| Production  | ReactDOM         | packages/react/react_dom_prod.js            |\n\nLastly, add the `.js` file that Dart will generate. The file will be the name of the `.dart` file that contains your `main` entrypoint, with `.js` at the end.\n\n\n```html\n\u003chtml\u003e\n  \u003chead\u003e\n    \u003c!-- ... --\u003e\n  \u003c/head\u003e\n  \u003cbody\u003e\n    \u003cdiv id=\"react_mount_point\"\u003eHere will be react content\u003c/div\u003e\n\n    \u003cscript src=\"packages/react/js/react.dev.js\"\u003e\u003c/script\u003e\n    \u003cscript defer src=\"your_dart_file_name.dart.js\"\u003e\u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n\u003e __Note:__ When serving your application in production, use `packages/react/js/react.min.js`\n  file instead of the un-minified `react.dev.js` shown in the example above.\n\n#### Dart App\n\nOnce you have an `.html` file containing the necessary `.js` files, you can initialize React\nin the `main` entrypoint of your Dart application.\n\n```dart\nimport 'dart:html';\n\nimport 'package:react/react.dart';\nimport 'package:react/react_dom.dart' as react_dom;\n\nmain() {\n  // Something to render... in this case a simple \u003cdiv\u003e with no props, and a string as its children.\n  var component = div({}, \"Hello world!\");\n\n  // Render it into the mount node we created in our .html file.\n  react_dom.render(component, querySelector('#react_mount_point'));\n}\n```\n\n## Build Stuff\n\n### Using browser native elements\n\nIf you are familiar with React (without JSX extension) React-dart shouldn't surprise you much. All elements are defined as\nfunctions that take `props` as first argument and `children` as optional second argument. `props` should implement `Map` and `children` is either one React element or `List` with multiple elements.\n\n```dart\nvar aDiv = div({\"className\": \"something\"}, [\n  h1({\"style\": {\"height\": \"20px\"}}, \"Headline\"),\n  a({\"href\":\"something.com\"}, \"Something\"),\n  \"Some text\"\n]);\n```\n\nFor event handlers you must provide function that takes a `SyntheticEvent` _(defined in this library)_.\n\n```dart\nvar aButton = button({\"onClick\": (SyntheticMouseEvent event) =\u003e print(event)});\n```\n\n### Defining custom components\n\n1. Define custom class that extends Component2 and implements - at a minimum - `render`.\n\n    ```dart\n    // cool_widget.dart\n\n    import 'package:react/react.dart';\n\n    class CoolWidgetComponent extends Component2 {\n      render() =\u003e div({}, \"CoolWidgetComponent\");\n    }\n    ```\n\n2. Then register the class so ReactJS can recognize it.\n\n    ```dart\n    var CoolWidget = registerComponent2(() =\u003e CoolWidgetComponent());\n    ```\n\n    \u003e __Warning:__ `registerComponent2` should be called only once per component and lifetime of application.\n\n3. Then you can use the registered component similarly as native elements.\n\n    ```dart\n    // app.dart\n\n    import 'dart:html';\n\n    import 'package:react/react.dart';\n    import 'package:react/react_dom.dart' as react_dom;\n\n    import 'cool_widget.dart';\n\n    main() {\n      react_dom.render(CoolWidget({}), querySelector('#react_mount_point'));\n    }\n    ```\n\n#### Custom component with props\n\n```dart\n// cool_widget.dart\n\nimport 'package:react/react.dart';\n\nclass CoolWidgetComponent extends Component2 {\n  @override\n  render() {\n    return div({}, props['text']);\n  }\n}\n\nvar CoolWidget = registerComponent2(() =\u003e CoolWidgetComponent());\n```\n\n```dart\n// app.dart\n\nimport 'dart:html';\n\nimport 'package:react/react.dart';\nimport 'package:react/react_dom.dart' as react_dom;\n\nimport 'cool_widget.dart';\n\nmain() {\n  react_dom.render(CoolWidget({\"text\": \"Something\"}), querySelector('#react_mount_point'));\n}\n```\n\n#### Custom component with a typed interface\n\n\u003e __Note:__ The typed interface capabilities of this library are fairly limited, and can result in\n  extremely verbose implementations. We strongly recommend using the\n  [OverReact](https://pub.dev/packages/over_react) package - which\n  makes creating statically-typed React UI components using Dart easy.\n\n```dart\n// cool_widget.dart\ntypedef CoolWidgetType({String headline, String text, int counter});\n\nvar _CoolWidget = registerComponent2(() =\u003e CoolWidgetComponent());\n\nCoolWidgetType CoolWidget({String headline, String text, int counter}) {\n  return _CoolWidget({'headline':headline, 'text':text});\n}\n\nclass CoolWidgetComponent extends Component2 {\n  String get headline =\u003e props['headline'];\n  String get text =\u003e props['text'];\n  int get counter =\u003e props['counter'];\n\n  @override\n  render() {\n    return div({},\n      h1({}, headline),\n      span({}, text),\n      span({}, counter),\n    );\n  }\n}\n```\n\n```dart\n// app.dart\n\nimport 'dart:html';\n\nimport 'package:react/react.dart';\nimport 'package:react/react_dom.dart' as react_dom;\n\nimport 'cool_widget.dart';\n\nvoid main() {\n  react_dom.render(\n    myComponent(\n        headline: \"My custom headline\",\n        text: \"My custom text\",\n        counter: 3,\n    ),\n    querySelector('#react_mount_point')\n  );\n}\n```\n\n#### React Component Lifecycle methods\n\nThe `Component2` class mirrors ReactJS' `React.Component` class, and contains all the same methods.\n\n\u003e See: [ReactJS Lifecycle Method Documentation](https://reactjs.org/docs/react-component.html) for more information.\n\n```dart\nclass MyComponent extends Component2 {\n  @override\n  void componentWillMount() {}\n\n  @override\n  void componentDidMount() {}\n\n  @override\n  void componentWillReceiveProps(Map nextProps) {}\n\n  @override\n  void componentWillUpdate(Map nextProps, Map nextState) {}\n\n  @override\n  void componentDidUpdate(Map prevProps, Map prevState) {}\n\n  @override\n  void componentWillUnmount() {}\n\n  @override\n  bool shouldComponentUpdate(Map nextProps, Map nextState) =\u003e true;\n\n  @override\n  Map getInitialState() =\u003e {};\n\n  @override\n  Map getDefaultProps() =\u003e {};\n\n  @override\n  render() =\u003e div({}, props['text']);\n}\n```\n\n#### Using refs and findDOMNode\n\nThe use of component `ref`s in react-dart is a bit different from React JS.\n\n* You can specify a ref name in component props and then call ref method to get the referenced element.\n* Return values for Dart components, DOM components and JavaScript components are different.\n    * For a Dart component, you get an instance of the Dart class of the component.\n    * For primitive components (like DOM elements), you get the DOM node.\n    * For JavaScript composite components, you get a `ReactElement` representing the react component.\n\nIf you want to work with DOM nodes of dart or JS components instead,\nyou can call top level `findDOMNode` on anything the ref returns.\n\n```dart\nvar DartComponent = registerComponent2(() =\u003e _DartComponent());\nclass _DartComponent extends Component2 {\n  @override\n  render() =\u003e div({});\n\n  void someInstanceMethod(int count) {\n    window.alert('count: $count');\n  }\n}\n\nvar ParentComponent = registerComponent2(() =\u003e _ParentComponent());\nclass _ParentComponent extends Component2 {\n  final inputRef = createRef\u003cInputElement\u003e(); // inputRef.current is the DOM node.\n  final dartComponentRef = createRef\u003c_DartComponent\u003e(); // dartComponentRef.current is the instance of _DartComponent\n\n  @override\n  void componentDidMount() {\n    print(inputRef.current.value); // Prints \"hello\" to the console.\n\n    dartComponentRef.current.someInstanceMethod(5); // Calls the method defined in _DartComponent\n    react_dom.findDOMNode(dartComponentRef); // Returns div element rendered from _DartComponent\n\n    react_dom.findDOMNode(this); // Returns root dom element rendered from this component\n  }\n\n  @override\n  render() {\n    return div({},\n      input({\"ref\": inputRef, \"defaultValue\": \"hello\"}),\n      DartComponent({\"ref\": dartComponentRef}),\n    );\n  }\n}\n```\n\n### Example Application\n\nFor more robust examples take a look at our [examples](https://github.com/Workiva/react-dart/tree/master/example).\n\n\n\n## Unit Testing Utilities\n\n[lib/react_test_utils.dart](https://github.com/Workiva/react-dart/blob/master/lib/react_test_utils.dart) is a\nDart wrapper for the [ReactJS TestUtils](https://reactjs.org/docs/test-utils.html) library allowing for unit tests\nto be made for React components in Dart.\n\nHere is an example of how to use `package:react/react_test_utils.dart` within a Dart test.\n\n```dart\nimport 'package:test/test.dart';\nimport 'package:react/react.dart' as react;\nimport 'package:react/react_dom.dart' as react_dom;\nimport 'package:react/react_test_utils.dart' as react_test_utils;\n\nclass MyTestComponent extends react.Component2 {\n  @override\n  Map getInitialState() =\u003e {'text': 'testing...'};\n\n  @override\n  render() {\n    return react.div({},\n        react.button({'onClick': (_) =\u003e setState({'text': 'success'})}),\n        react.span({'className': 'spanText'}, state['text']),\n    );\n  }\n}\n\nvar myTestComponent = react.registerComponent2(() =\u003e new MyTestComponent());\n\nvoid main() {\n  test('should click button and set span text to \"success\"', () {\n    var component = react_test_utils.renderIntoDocument(myTestComponent({}));\n\n    // Find button using tag name\n    var buttonElement = react_test_utils.findRenderedDOMComponentWithTag(\n        component, 'button');\n\n    // Find span using class name\n    var spanElement = react_test_utils.findRenderedDOMComponentWithClass(\n        component, 'spanText');\n\n    var buttonNode = react_dom.findDOMNode(buttonElement);\n    var spanNode = react_dom.findDOMNode(spanElement);\n\n    // Span text should equal the initial state\n    expect(spanNode.text, equals('testing...'));\n\n    // Click the button and trigger the onClick event\n    react_test_utils.Simulate.click(buttonNode);\n\n    // Span text should change to 'success'\n    expect(spanNode.text, equals('success'));\n  });\n}\n```\n\n\n## Contributing\n\nFormat using\n```bash\ndart format -l 120 .\n```\n\nWhile we'd like to adhere to the recommended line length of 80, it's too short for much of the code\nrepo written before a formatter was use, causing excessive wrapping and code that's hard to read.\n\nSo, we use a line length of 120 instead.\n\n### Running Tests\n\n#### dart2js\n\n```bash\ndart run build_runner test --release -- --preset dart2js\n```\n\n\u003e NOTE: When using Dart SDK \u003c 2.14.0, use `--preset dart2js-legacy` instead.\n\n#### Dart Dev Compiler (\"DDC\")\n\n```bash\ndart run build_runner test -- --preset dartdevc\n```\n\n\u003e NOTE: When using Dart SDK \u003c 2.14.0, use `--preset dartdevc-legacy` instead.\n\n### Building React JS Source Files\n\nMake sure the packages you need are dependencies in `package.json` then run:\n```bash\nyarn install\n```\n\nAfter modifying files any files in ./js_src/, run:\n\n```bash\nyarn run build\n```\n","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWorkiva%2Freact-dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FWorkiva%2Freact-dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWorkiva%2Freact-dart/lists"}