diff --git a/fixtures/flight-browser/index.html b/fixtures/flight-browser/index.html
new file mode 100644
index 0000000000000..5f522a9b3a1a0
--- /dev/null
+++ b/fixtures/flight-browser/index.html
@@ -0,0 +1,84 @@
+
+
+
+
+ Flight Example
+
+
+ Flight Example
+
+
+ To install React, follow the instructions on
+ GitHub.
+
+
+ If you can see this, React is not working right.
+ If you checked out the source from GitHub make sure to run npm run build
.
+
+
+
+
+
+
+
+
+
diff --git a/packages/react-dom/npm/unstable-flight-client.js b/packages/react-dom/npm/unstable-flight-client.js
new file mode 100644
index 0000000000000..9116c361ebf74
--- /dev/null
+++ b/packages/react-dom/npm/unstable-flight-client.js
@@ -0,0 +1,7 @@
+'use strict';
+
+if (process.env.NODE_ENV === 'production') {
+ module.exports = require('./cjs/react-dom-unstable-flight-client.production.min.js');
+} else {
+ module.exports = require('./cjs/react-dom-unstable-flight-client.development.js');
+}
diff --git a/packages/react-dom/npm/unstable-flight-server.browser.js b/packages/react-dom/npm/unstable-flight-server.browser.js
new file mode 100644
index 0000000000000..8a6b19b7ab1cf
--- /dev/null
+++ b/packages/react-dom/npm/unstable-flight-server.browser.js
@@ -0,0 +1,7 @@
+'use strict';
+
+if (process.env.NODE_ENV === 'production') {
+ module.exports = require('./cjs/react-dom-unstable-flight-server.browser.production.min.js');
+} else {
+ module.exports = require('./cjs/react-dom-unstable-flight-server.browser.development.js');
+}
diff --git a/packages/react-dom/npm/unstable-flight-server.js b/packages/react-dom/npm/unstable-flight-server.js
new file mode 100644
index 0000000000000..4b75a8eef3b45
--- /dev/null
+++ b/packages/react-dom/npm/unstable-flight-server.js
@@ -0,0 +1,3 @@
+'use strict';
+
+module.exports = require('./unstable-flight-server.node');
diff --git a/packages/react-dom/npm/unstable-flight-server.node.js b/packages/react-dom/npm/unstable-flight-server.node.js
new file mode 100644
index 0000000000000..30b967fd425da
--- /dev/null
+++ b/packages/react-dom/npm/unstable-flight-server.node.js
@@ -0,0 +1,7 @@
+'use strict';
+
+if (process.env.NODE_ENV === 'production') {
+ module.exports = require('./cjs/react-dom-unstable-flight-server.node.production.min.js');
+} else {
+ module.exports = require('./cjs/react-dom-unstable-flight-server.node.development.js');
+}
diff --git a/packages/react-dom/package.json b/packages/react-dom/package.json
index e05cac2ff5103..b413c885be8d0 100644
--- a/packages/react-dom/package.json
+++ b/packages/react-dom/package.json
@@ -39,13 +39,17 @@
"unstable-fizz.js",
"unstable-fizz.browser.js",
"unstable-fizz.node.js",
+ "unstable-flight-server.js",
+ "unstable-flight-server.browser.js",
+ "unstable-flight-server.node.js",
"unstable-native-dependencies.js",
"cjs/",
"umd/"
],
"browser": {
"./server.js": "./server.browser.js",
- "./unstable-fizz.js": "./unstable-fizz.browser.js"
+ "./unstable-fizz.js": "./unstable-fizz.browser.js",
+ "./unstable-flight-server.js": "./unstable-flight-server.browser.js"
},
"browserify": {
"transform": [
diff --git a/packages/react-dom/src/client/flight/ReactFlightDOMClient.js b/packages/react-dom/src/client/flight/ReactFlightDOMClient.js
new file mode 100644
index 0000000000000..18bc4753a5294
--- /dev/null
+++ b/packages/react-dom/src/client/flight/ReactFlightDOMClient.js
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @flow
+ */
+
+import type {ReactModel} from 'react-flight/src/ReactFlightClient';
+
+import {
+ createRequest,
+ startWork,
+ startFlowing,
+} from 'react-flight/inline.dom-browser';
+
+function renderToReadableStream(model: ReactModel): ReadableStream {
+ let request;
+ return new ReadableStream({
+ start(controller) {
+ request = createRequest(model, controller);
+ startWork(request);
+ },
+ pull(controller) {
+ startFlowing(request, controller.desiredSize);
+ },
+ cancel(reason) {},
+ });
+}
+
+export default {
+ renderToReadableStream,
+};
diff --git a/packages/react-dom/src/client/flight/ReactFlightDOMHostConfig.js b/packages/react-dom/src/client/flight/ReactFlightDOMHostConfig.js
new file mode 100644
index 0000000000000..9dde4993ad6ad
--- /dev/null
+++ b/packages/react-dom/src/client/flight/ReactFlightDOMHostConfig.js
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @flow
+ */
+
+export type Destination = ReadableStreamController;
+
+export function scheduleWork(callback: () => void) {
+ callback();
+}
+
+export function flushBuffered(destination: Destination) {
+ // WHATWG Streams do not yet have a way to flush the underlying
+ // transform streams. https://github.com/whatwg/streams/issues/960
+}
+
+export function beginWriting(destination: Destination) {}
+
+export function writeChunk(destination: Destination, buffer: Uint8Array) {
+ destination.enqueue(buffer);
+}
+
+export function completeWriting(destination: Destination) {}
+
+export function close(destination: Destination) {
+ destination.close();
+}
+
+const textEncoder = new TextEncoder();
+
+export function convertStringToBuffer(content: string): Uint8Array {
+ return textEncoder.encode(content);
+}
+
+export function formatChunkAsString(type: string, props: Object): string {
+ let str = '<' + type + '>';
+ if (typeof props.children === 'string') {
+ str += props.children;
+ }
+ str += '' + type + '>';
+ return str;
+}
+
+export function formatChunk(type: string, props: Object): Uint8Array {
+ return convertStringToBuffer(formatChunkAsString(type, props));
+}
diff --git a/packages/react-dom/src/client/flight/__tests__/ReactFlightDOMBrowser-test.js b/packages/react-dom/src/client/flight/__tests__/ReactFlightDOMBrowser-test.js
new file mode 100644
index 0000000000000..39b0956553558
--- /dev/null
+++ b/packages/react-dom/src/client/flight/__tests__/ReactFlightDOMBrowser-test.js
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ *
+ * @emails react-core
+ */
+
+'use strict';
+
+// Polyfills for test environment
+global.ReadableStream = require('@mattiasbuelens/web-streams-polyfill/ponyfill/es6').ReadableStream;
+global.TextEncoder = require('util').TextEncoder;
+
+let React;
+let ReactFlightDOMServer;
+
+describe('ReactFlightDOM', () => {
+ beforeEach(() => {
+ jest.resetModules();
+ React = require('react');
+ ReactFlightDOMServer = require('react-dom/unstable-flight-server.browser');
+ });
+
+ async function readResult(stream) {
+ let reader = stream.getReader();
+ let result = '';
+ while (true) {
+ let {done, value} = await reader.read();
+ if (done) {
+ return result;
+ }
+ result += Buffer.from(value).toString('utf8');
+ }
+ }
+
+ it('should resolve HTML', async () => {
+ function Text({children}) {
+ return {children};
+ }
+ function HTML() {
+ return (
+
+ hello
+ world
+
+ );
+ }
+
+ let model = {
+ html: