diff --git a/code/edited-first-app/package.json b/code/edited-first-app/package.json
new file mode 100644
index 0000000000..0f1f6dfeb8
--- /dev/null
+++ b/code/edited-first-app/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "first-react-app",
+ "version": "1.0.0",
+ "description": "",
+ "keywords": [],
+ "main": "src/index.js",
+ "dependencies": {
+ "loader-utils": "3.2.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-scripts": "5.0.1"
+ },
+ "devDependencies": {
+ "@babel/runtime": "7.13.8",
+ "typescript": "4.1.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/code/edited-first-app/public/index.html b/code/edited-first-app/public/index.html
new file mode 100644
index 0000000000..42ae2d2dcb
--- /dev/null
+++ b/code/edited-first-app/public/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/edited-first-app/public/react-logo-xs.png b/code/edited-first-app/public/react-logo-xs.png
new file mode 100644
index 0000000000..4804cccc98
Binary files /dev/null and b/code/edited-first-app/public/react-logo-xs.png differ
diff --git a/code/edited-first-app/src/App.js b/code/edited-first-app/src/App.js
new file mode 100644
index 0000000000..065c1d7c21
--- /dev/null
+++ b/code/edited-first-app/src/App.js
@@ -0,0 +1,80 @@
+import { useState } from "react";
+import "./styles.css";
+
+const content = [
+ [
+ "React is extremely popular",
+ "It makes building complex, interactive UIs a breeze",
+ "It's powerful & flexible",
+ "It has a very active and versatile ecosystem"
+ ],
+ [
+ "Components, JSX & Props",
+ "State",
+ "Hooks (e.g., useEffect())",
+ "Dynamic rendering"
+ ],
+ [
+ "Official web page (react.dev)",
+ "Next.js (Fullstack framework)",
+ "React Native (build native mobile apps with React)"
+ ],
+ [
+ "Vanilla JavaScript requires imperative programming",
+ "Imperative Programming: You define all the steps needed to achieve a result",
+ "React on the other hand embraces declarative programming",
+ "With React, you define the goal and React figures out how to get there"
+ ]
+];
+
+export default function App() {
+ const [activeContentIndex, setActiveContentIndex] = useState(0);
+
+ return (
+
+
+
+
+
+
+
+ {content[activeContentIndex].map((item) => (
+ - {item}
+ ))}
+
+
+
+
+ );
+}
diff --git a/code/edited-first-app/src/index.js b/code/edited-first-app/src/index.js
new file mode 100644
index 0000000000..c223b562cf
--- /dev/null
+++ b/code/edited-first-app/src/index.js
@@ -0,0 +1,13 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+
+import App from "./App";
+
+const rootElement = document.getElementById("root");
+const root = createRoot(rootElement);
+
+root.render(
+
+
+
+);
diff --git a/code/edited-first-app/src/styles.css b/code/edited-first-app/src/styles.css
new file mode 100644
index 0000000000..46cc4732af
--- /dev/null
+++ b/code/edited-first-app/src/styles.css
@@ -0,0 +1,74 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: sans-serif;
+ background-color: #181c1f;
+ color: #bdd1d4;
+ margin: 2rem;
+}
+
+header {
+ margin: 2rem 0;
+ display: flex;
+ gap: 1.5rem;
+ align-items: center;
+}
+
+header img {
+ width: 3rem;
+ object-fit: contain;
+}
+
+header h1 {
+ margin: 0;
+ color: #48d9f3;
+}
+
+header p {
+ margin: 0;
+ color: #82c2ce;
+}
+
+#tabs {
+ max-width: 32rem;
+ margin: 2rem 0;
+ overflow: hidden;
+}
+
+#tabs menu {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ gap: 0.25rem;
+}
+
+#tabs button {
+ font: inherit;
+ font-size: 0.85rem;
+ background-color: #282f33;
+ border: none;
+ border-bottom-color: #48d9f3;
+ color: #e0eff1;
+ border-radius: 4px 4px 0 0;
+ padding: 0.75rem 1rem;
+ cursor: pointer;
+ transition: all 0.2s ease-out;
+}
+
+#tabs button:hover,
+#tabs button.active {
+ background-color: #48d9f3;
+ color: #273133;
+}
+
+#tab-content {
+ background-color: #2d3942;
+ border-radius: 0 4px 4px 4px;
+ padding: 1rem;
+}
+
+#tab-content li {
+ margin: 0.75rem 0;
+}
diff --git a/code/react-vs-vanilla-js-example/just-js/index.html b/code/react-vs-vanilla-js-example/just-js/index.html
new file mode 100644
index 0000000000..6a81daa0a6
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/just-js/index.html
@@ -0,0 +1,28 @@
+
+
+
+ Vanilla JavaScript
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/code/react-vs-vanilla-js-example/just-js/index.js b/code/react-vs-vanilla-js-example/just-js/index.js
new file mode 100644
index 0000000000..4aaf2ddac7
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/just-js/index.js
@@ -0,0 +1,61 @@
+const content = [
+ [
+ "React is extremely popular",
+ "It makes building complex, interactive UIs a breeze",
+ "It's powerful & flexible",
+ "It has a very active and versatile ecosystem"
+ ],
+ [
+ "Components, JSX & Props",
+ "State",
+ "Hooks (e.g., useEffect())",
+ "Dynamic rendering"
+ ],
+ [
+ "Official web page (react.dev)",
+ "Next.js (Fullstack framework)",
+ "React Native (build native mobile apps with React)"
+ ]
+];
+
+const btnWhyReact = document.getElementById("btn-why-react");
+const btnCoreFeature = document.getElementById("btn-core-features");
+const btnResources = document.getElementById("btn-resources");
+const tabContent = document.getElementById("tab-content");
+
+function displayContent(items) {
+ let listContent = "";
+ for (const item of items) {
+ listContent += `${item}`;
+ }
+ const list = document.createElement("ul");
+ tabContent.innerHTML = ""; // clear existing content
+ list.innerHTML = listContent; // insert new content
+ tabContent.append(list);
+}
+
+function highlightButton(btn) {
+ // Clear all existing styling / highlights
+ btnWhyReact.className = "";
+ btnCoreFeature.className = "";
+ btnResources.className = "";
+ btn.className = "active"; // set new style / highlight
+}
+
+function handleClick(event) {
+ const btnId = event.target.id;
+ highlightButton(event.target);
+ if (btnId === "btn-why-react") {
+ displayContent(content[0]);
+ } else if (btnId === "btn-core-features") {
+ displayContent(content[1]);
+ } else {
+ displayContent(content[2]);
+ }
+}
+
+displayContent(content[0]); // initially show this content
+
+btnWhyReact.addEventListener("click", handleClick);
+btnCoreFeature.addEventListener("click", handleClick);
+btnResources.addEventListener("click", handleClick);
diff --git a/code/react-vs-vanilla-js-example/just-js/js-logo-xs.png b/code/react-vs-vanilla-js-example/just-js/js-logo-xs.png
new file mode 100644
index 0000000000..87ec726a73
Binary files /dev/null and b/code/react-vs-vanilla-js-example/just-js/js-logo-xs.png differ
diff --git a/code/react-vs-vanilla-js-example/just-js/styles.css b/code/react-vs-vanilla-js-example/just-js/styles.css
new file mode 100644
index 0000000000..6561d2d166
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/just-js/styles.css
@@ -0,0 +1,74 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: sans-serif;
+ background-color: #181c1f;
+ color: #bdd1d4;
+ margin: 2rem;
+}
+
+header {
+ margin: 2rem 0;
+ display: flex;
+ gap: 1.5rem;
+ align-items: center;
+}
+
+header img {
+ width: 3rem;
+ object-fit: contain;
+}
+
+header h1 {
+ margin: 0;
+ color: #f3e248;
+}
+
+header p {
+ margin: 0;
+ color: #dbd7b1;
+}
+
+#tabs {
+ max-width: 32rem;
+ margin: 2rem 0;
+ overflow: hidden;
+}
+
+#tabs menu {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ gap: 0.25rem;
+}
+
+#tabs button {
+ font: inherit;
+ font-size: 0.85rem;
+ background-color: #282f33;
+ border: none;
+ border-bottom-color: #f3e248;
+ color: #e0eff1;
+ border-radius: 4px 4px 0 0;
+ padding: 0.75rem 1rem;
+ cursor: pointer;
+ transition: all 0.2s ease-out;
+}
+
+#tabs button:hover,
+#tabs button.active {
+ background-color: #f3e248;
+ color: #273133;
+}
+
+#tab-content {
+ background-color: #2d3942;
+ border-radius: 0 4px 4px 4px;
+ padding: 1rem;
+}
+
+#tab-content li {
+ margin: 0.75rem 0;
+}
diff --git a/code/react-vs-vanilla-js-example/react/package.json b/code/react-vs-vanilla-js-example/react/package.json
new file mode 100644
index 0000000000..9ed58519ba
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/react/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "react-vs-vanilla-demo",
+ "version": "1.0.0",
+ "description": "",
+ "keywords": [],
+ "main": "src/index.js",
+ "dependencies": {
+ "loader-utils": "3.2.1",
+ "react": "18.2.0",
+ "react-dom": "18.2.0",
+ "react-scripts": "5.0.1"
+ },
+ "devDependencies": {
+ "@babel/runtime": "7.13.8",
+ "typescript": "4.1.3"
+ },
+ "scripts": {
+ "start": "react-scripts start",
+ "build": "react-scripts build",
+ "test": "react-scripts test --env=jsdom",
+ "eject": "react-scripts eject"
+ },
+ "browserslist": [
+ ">0.2%",
+ "not dead",
+ "not ie <= 11",
+ "not op_mini all"
+ ]
+}
\ No newline at end of file
diff --git a/code/react-vs-vanilla-js-example/react/public/index.html b/code/react-vs-vanilla-js-example/react/public/index.html
new file mode 100644
index 0000000000..42ae2d2dcb
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/react/public/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+
+
+ React App
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/code/react-vs-vanilla-js-example/react/public/react-logo-xs.png b/code/react-vs-vanilla-js-example/react/public/react-logo-xs.png
new file mode 100644
index 0000000000..4804cccc98
Binary files /dev/null and b/code/react-vs-vanilla-js-example/react/public/react-logo-xs.png differ
diff --git a/code/react-vs-vanilla-js-example/react/src/App.js b/code/react-vs-vanilla-js-example/react/src/App.js
new file mode 100644
index 0000000000..503670ec7c
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/react/src/App.js
@@ -0,0 +1,68 @@
+import { useState } from "react";
+import "./styles.css";
+
+const content = [
+ [
+ "React is extremely popular",
+ "It makes building complex, interactive UIs a breeze",
+ "It's powerful & flexible",
+ "It has a very active and versatile ecosystem"
+ ],
+ [
+ "Components, JSX & Props",
+ "State",
+ "Hooks (e.g., useEffect())",
+ "Dynamic rendering"
+ ],
+ [
+ "Official web page (react.dev)",
+ "Next.js (Fullstack framework)",
+ "React Native (build native mobile apps with React)"
+ ]
+];
+
+export default function App() {
+ const [activeContentIndex, setActiveContentIndex] = useState(0);
+
+ return (
+
+
+
+
+
+
+
+ {content[activeContentIndex].map((item) => (
+ - {item}
+ ))}
+
+
+
+
+ );
+}
diff --git a/code/react-vs-vanilla-js-example/react/src/index.js b/code/react-vs-vanilla-js-example/react/src/index.js
new file mode 100644
index 0000000000..c223b562cf
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/react/src/index.js
@@ -0,0 +1,13 @@
+import { StrictMode } from "react";
+import { createRoot } from "react-dom/client";
+
+import App from "./App";
+
+const rootElement = document.getElementById("root");
+const root = createRoot(rootElement);
+
+root.render(
+
+
+
+);
diff --git a/code/react-vs-vanilla-js-example/react/src/styles.css b/code/react-vs-vanilla-js-example/react/src/styles.css
new file mode 100644
index 0000000000..46cc4732af
--- /dev/null
+++ b/code/react-vs-vanilla-js-example/react/src/styles.css
@@ -0,0 +1,74 @@
+* {
+ box-sizing: border-box;
+}
+
+body {
+ font-family: sans-serif;
+ background-color: #181c1f;
+ color: #bdd1d4;
+ margin: 2rem;
+}
+
+header {
+ margin: 2rem 0;
+ display: flex;
+ gap: 1.5rem;
+ align-items: center;
+}
+
+header img {
+ width: 3rem;
+ object-fit: contain;
+}
+
+header h1 {
+ margin: 0;
+ color: #48d9f3;
+}
+
+header p {
+ margin: 0;
+ color: #82c2ce;
+}
+
+#tabs {
+ max-width: 32rem;
+ margin: 2rem 0;
+ overflow: hidden;
+}
+
+#tabs menu {
+ margin: 0;
+ padding: 0;
+ display: flex;
+ gap: 0.25rem;
+}
+
+#tabs button {
+ font: inherit;
+ font-size: 0.85rem;
+ background-color: #282f33;
+ border: none;
+ border-bottom-color: #48d9f3;
+ color: #e0eff1;
+ border-radius: 4px 4px 0 0;
+ padding: 0.75rem 1rem;
+ cursor: pointer;
+ transition: all 0.2s ease-out;
+}
+
+#tabs button:hover,
+#tabs button.active {
+ background-color: #48d9f3;
+ color: #273133;
+}
+
+#tab-content {
+ background-color: #2d3942;
+ border-radius: 0 4px 4px 4px;
+ padding: 1rem;
+}
+
+#tab-content li {
+ margin: 0.75rem 0;
+}
diff --git a/slides/slides.pdf b/slides/slides.pdf
new file mode 100644
index 0000000000..e7b2f655b1
Binary files /dev/null and b/slides/slides.pdf differ