aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-07-05 02:25:33 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-07-05 02:25:33 -0700
commit2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9 (patch)
tree1f8060994a8027d7a8ec7de7a770dc763d9d3f08
parent2d8dfeff49a543054e9390c505337386aaf1cd9b (diff)
downloadbun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.tar.gz
bun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.tar.zst
bun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.zip
Current landing
-rw-r--r--packages/bun-landing/build.tsx15
-rw-r--r--packages/bun-landing/index.css166
-rw-r--r--packages/bun-landing/page.tsx312
-rw-r--r--packages/bun-landing/public/index.css874
-rw-r--r--packages/bun-landing/public/index.html197
-rw-r--r--packages/bun-landing/ssr.tsx12
6 files changed, 1288 insertions, 288 deletions
diff --git a/packages/bun-landing/build.tsx b/packages/bun-landing/build.tsx
new file mode 100644
index 000000000..2be819a96
--- /dev/null
+++ b/packages/bun-landing/build.tsx
@@ -0,0 +1,15 @@
+import { file, serve } from "bun";
+import "shiki";
+import { renderToReadableStream } from "../../test/bun.js/reactdom-bun";
+
+import liveReload from "bun-livereload";
+import { join } from "path";
+
+const { default: Page } = await import("./page.tsx");
+const build = await new Response(await renderToReadableStream(<Page />)).text();
+
+await Bun.write(import.meta.dir + "/public/index.html", build);
+await Bun.write(
+ import.meta.dir + "/public/index.css",
+ Bun.file(import.meta.dir + "/index.css")
+);
diff --git a/packages/bun-landing/index.css b/packages/bun-landing/index.css
index 25a7d1382..bd1b41e96 100644
--- a/packages/bun-landing/index.css
+++ b/packages/bun-landing/index.css
@@ -128,7 +128,7 @@ nav {
header {
display: grid;
- grid-template-columns: auto max-content min-content;
+ grid-template-columns: auto max-content;
background-color: var(--black);
padding: 1.5rem 3rem;
align-items: center;
@@ -311,10 +311,18 @@ header {
text-align: center;
padding-bottom: 8px;
border-bottom: 1px solid #ccc;
+ cursor: pointer;
}
-.Tab--active {
+.Tab[data-tab="react"]:hover,
+.Graphs--active-react .Tab[data-tab="react"],
+.Tab[data-tab="sqlite"]:hover,
+.Graphs--active-sqlite .Tab[data-tab="sqlite"],
+.Tab[data-tab="ffi"]:hover,
+.Graphs--active-ffi .Tab[data-tab="ffi"] {
border-bottom-color: aquamarine;
+ border-right-color: aquamarine;
+ border-left-color: aquamarine;
}
.BarGraph {
@@ -370,7 +378,7 @@ header {
.BarGraph,
.BarGraphBar-label,
.BarGraphItem {
- --level: calc(var(--amount) / 50000);
+ --level: calc(var(--amount) / var(--max));
--inverse: calc(1 / var(--level));
}
@@ -380,7 +388,7 @@ header {
width: var(--primary);
height: var(--opposite);
- background-color: pink;
+ background-color: rgb(93, 89, 134);
transform-origin: bottom center;
transform: scaleY(var(--level));
position: relative;
@@ -432,7 +440,7 @@ header {
.BarGraphItem--bun .BarGraphBar {
background-color: rgb(249, 241, 225);
box-shadow: inset 1px 1px 3px rgb(204, 198, 187);
- background-image: url("/public/logo.png");
+ background-image: url("/logo.png");
background-repeat: no-repeat;
background-size: 56px 48.8px;
background-position: 6px 20%;
@@ -473,11 +481,28 @@ header {
.BarGraphKeyItem-label {
color: white;
}
+
.BarGraphKeyItem-value {
color: #666;
margin-top: 0.5rem;
}
+.BarGraphKeyItem-viewSource {
+ margin-top: 0.5rem;
+ color: #666;
+ text-transform: lowercase;
+ font-weight: thin;
+ font-size: 0.8rem;
+}
+
+.BarGraphKeyItem:hover {
+ text-decoration: none;
+}
+
+.BarGraphKeyItem:hover .BarGraphKeyItem-viewSource {
+ color: var(--orange-light);
+}
+
.DemphasizedLabel {
text-transform: uppercase;
white-space: nowrap;
@@ -646,7 +671,7 @@ li {
.Graphs,
.BarGraph,
.BarGraphList {
- max-width: calc(100vw - (var(--horizontal-padding) * 2));
+ max-width: auto;
}
.BarGraph {
@@ -676,12 +701,7 @@ li {
}
.InstallBox--mobile {
- padding: calc(var(--vertical-padding) * 1.5) var(--horizontal-padding);
- margin: calc(-1 * var(--vertical-padding))
- calc(-1 * var(--horizontal-padding));
- box-sizing: content-box;
border-radius: 0;
- max-width: calc(100vw - (var(--horizontal-padding) * 2));
}
@media (max-width: 599px) {
@@ -728,5 +748,127 @@ li {
padding: 0.25rem;
border-radius: 8px;
text-decoration: none !important;
- margin-right: 0.2rem;
+}
+
+.PerformanceClaim {
+ text-decoration: dashed underline 2px #000 !important;
+ text-decoration-skip-ink: auto !important;
+}
+
+.BarGraph--react,
+.BarGraph--ffi,
+.BarGraph--sqlite {
+ display: none;
+}
+
+.Graphs--active-react .BarGraph--react,
+.Graphs--active-ffi .BarGraph--ffi,
+.Graphs--active-sqlite .BarGraph--sqlite {
+ display: block;
+}
+
+@media (min-width: 930px) {
+ .Graphs {
+ margin-left: auto;
+ }
+
+ .BarGraph-subheading,
+ .BarGraph-heading {
+ text-align: center;
+ }
+ .BarGraph-heading {
+ margin-bottom: 0.25rem;
+ }
+
+ .BarGraphKeyItem-label {
+ width: 130px;
+ }
+}
+
+@media (max-width: 929px) {
+ #code-box {
+ width: fit-content;
+ }
+
+ .CodeBlock .shiki {
+ padding: 24px 16px;
+ margin: calc(-1 * var(--horizontal-padding));
+ width: calc(
+ 100vw - var(--horizontal-padding) - var(--horizontal-padding) -2px
+ );
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ border-radius: 0;
+ font-size: 0.8rem;
+ }
+
+ .logo-link {
+ gap: 0;
+ }
+
+ header {
+ grid-template-columns: min-content auto;
+ gap: 2rem;
+ }
+
+ .Tabs {
+ }
+
+ .tagline,
+ .subtitle,
+ .BarGraph-heading,
+ .BarGraph-subheading {
+ padding: 0 var(--horizontal-padding);
+ }
+
+ main {
+ padding-left: 0;
+ padding-right: 0;
+ text-align: left;
+ }
+
+ .InstallBox {
+ padding: 24px 16px;
+ margin-bottom: -32px;
+ }
+
+ .tagline {
+ font-size: 30pt;
+ }
+
+ .Tag--Command {
+ display: block;
+ width: fit-content;
+ margin-bottom: 1rem;
+ }
+
+ .Tabs {
+ margin: 0;
+ gap: 0rem;
+ width: 100%;
+ }
+
+ .Tab {
+ width: 100%;
+ padding-top: 16px;
+ padding-bottom: 16px;
+ }
+
+ .Tab {
+ border-bottom-color: #333;
+ }
+
+ #pitch-content {
+ max-width: 100%;
+ }
+
+ .Graphs--active-react .Tab[data-tab="react"],
+ .Graphs--active-sqlite .Tab[data-tab="sqlite"],
+ .Graphs--active-ffi .Tab[data-tab="ffi"] {
+ background-color: rgba(100, 100, 100, 0.1);
+ }
+
+ .Tabs {
+ border-top: 1px solid rgba(200, 200, 200, 0.1);
+ }
}
diff --git a/packages/bun-landing/page.tsx b/packages/bun-landing/page.tsx
index 9162b5ef9..d255d8ff4 100644
--- a/packages/bun-landing/page.tsx
+++ b/packages/bun-landing/page.tsx
@@ -1,5 +1,6 @@
import * as shiki from "shiki";
+// because we don't want to wait for it to reload everytime this page reloads
globalThis._highlighter ||= await shiki.getHighlighter({
theme: "dracula",
});
@@ -45,7 +46,43 @@ const Bun = ({ children, href, Tag = href ? "a" : "span" }) => (
</Tag>
);
-const Zig = ({}) => (
+const fmt = new Intl.NumberFormat();
+
+const BarGraphItem = ({ type, amount = 0, label, max = 0 }) => (
+ <div
+ className={`BarGraphItem BarGraphItem--${type}`}
+ style={{ "--amount": amount, "--max": max }}
+ >
+ <div
+ style={{ "--amount": amount, "--max": max }}
+ title={`${amount} ${label}`}
+ className="BarGraphBar"
+ >
+ <div
+ style={{ "--amount": amount, "--max": max }}
+ className="BarGraphBar-label"
+ >
+ {fmt.format(amount)}
+ </div>
+ </div>
+ </div>
+);
+
+const BarGraphLabel = ({ name, version, source }) => (
+ <a href={source} target="_blank" className="BarGraphKeyItem">
+ <div className="BarGraphKeyItem-label">{name}</div>
+ <div className="BarGraphKeyItem-value">{version}</div>
+ <div className="BarGraphKeyItem-viewSource">View source</div>
+ </a>
+);
+
+const PerformanceClaim = ({ href, children }) => (
+ <a href={href} target="_blank" className="PerformanceClaim">
+ {children}
+ </a>
+);
+
+const Zig = () => (
<svg
xmlns="http://www.w3.org/2000/svg"
height="1.2rem"
@@ -162,8 +199,8 @@ export default () => (
<div id="header-wrap">
<header>
<a href="/" id="logo-link">
- <img src="/public/logo@2x.png" alt="Bun" id="logo" />
- <img src="/public/Bun@2x.png" alt="Bun" id="logo-text" />
+ <img src="/logo@2x.png" alt="Bun" id="logo" />
+ <img src="/Bun@2x.png" alt="Bun" id="logo-text" />
</a>
<nav className="Navigation">
@@ -183,7 +220,6 @@ export default () => (
</a>
</li>
</nav>
- <div id="HeaderInstallButton">Install</div>
</header>
</div>
<div id="pitch">
@@ -200,90 +236,170 @@ export default () => (
<InstallBox desktop />
</div>
- <div className="Graphs">
+ <div className="Graphs Graphs--active-react">
<div className="Tabs">
- <div className="Tab Tab--active">Bun.serve</div>
- <div className="Tab">bun:sqlite</div>
- <div className="Tab">bun:ffi</div>
+ <div data-tab="react" className="Tab">
+ Bun.serve
+ </div>
+ <div data-tab="sqlite" className="Tab">
+ bun:sqlite
+ </div>
+ <div data-tab="ffi" className="Tab">
+ bun:ffi
+ </div>
</div>
- <div className="ActiveTab">
- <div className="BarGraph BarGraph--horizontal BarGraph--dark">
- <div className="BarGraph-heading">HTTP requests per second</div>
+ <div id="active-tab" className="ActiveTab">
+ <div className="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark">
+ <div className="BarGraph-heading">
+ Server-side rendering React
+ </div>
+ <div title="oha -z 5s" className="BarGraph-subheading">
+ HTTP requests per second (Linux AMD64)
+ </div>
+
+ <div style={{ "--count": 3 }} className="BarGraphList">
+ <BarGraphItem
+ type="bun"
+ amount={48936}
+ label="requests per second"
+ max={Math.max(48936, 16288, 12289) * 1.25}
+ />
+ <BarGraphItem
+ type="node"
+ amount={16288}
+ label="requests per second"
+ max={Math.max(48936, 16288, 12289) * 1.25}
+ />
+ <BarGraphItem
+ type="deno"
+ amount={12289}
+ label="requests per second"
+ max={Math.max(48936, 16288, 12289) * 1.25}
+ />
+ </div>
+
+ <div style={{ "--count": 3 }} className="BarGraphKey">
+ <BarGraphLabel
+ name="bun"
+ version="v0.1.0"
+ source="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.jsx"
+ />
+ <BarGraphLabel
+ name="node"
+ version="v18.1.0"
+ source="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.deno.jsx"
+ />
+ <BarGraphLabel
+ name="deno"
+ version="v1.23.2"
+ source="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.node.jsx"
+ />
+ </div>
+ </div>
+
+ <div className="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark">
+ <div className="BarGraph-heading">
+ Average queries per second{" "}
+ </div>
+ <div className="BarGraph-subheading">
+ SELECT * from "Orders" (Northwind Traders)
+ </div>
+
+ <div style={{ "--count": 3 }} className="BarGraphList">
+ <BarGraphItem
+ type="bun"
+ amount={(1000 / 16.6).toFixed(2)}
+ label="queries per second"
+ max={Math.ceil(
+ Math.max(1000 / 16.6, 1000 / 42.96, 1000 / 104.69) * 1.25
+ )}
+ />
+ <BarGraphItem
+ type="better-sqlite3"
+ amount={(1000 / 42.96).toFixed(2)}
+ label="queries per second"
+ max={Math.ceil(
+ Math.max(1000 / 16.6, 1000 / 42.96, 1000 / 104.69) * 1.25
+ )}
+ />
+ <BarGraphItem
+ type="deno"
+ amount={(1000 / 104.69).toFixed(2)}
+ label="queries per second"
+ max={Math.ceil(
+ Math.max(1000 / 16.6, 1000 / 42.96, 1000 / 104.69) * 1.25
+ )}
+ />
+ </div>
+
+ <div style={{ "--count": 3 }} className="BarGraphKey">
+ <BarGraphLabel
+ name="bun:sqlite"
+ version="v0.1.0"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.js"
+ />
+ <BarGraphLabel
+ name="better-sqlite3"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.node.mjs"
+ version="node v18.2.0"
+ />
+ <BarGraphLabel
+ name="deno (x/sqlite)"
+ version="v1.23.2"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.deno.js"
+ />
+ </div>
+ </div>
+
+ <div className="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark">
+ <div className="BarGraph-heading">Operations per second</div>
<div className="BarGraph-subheading">
- Serving a 47 KB file * Bigger is better
+ Call add(1,2,3) from JavaScript
</div>
<div style={{ "--count": 3 }} className="BarGraphList">
- <div
- className="BarGraphItem BarGraphItem--bun"
- style={{ "--amount": 41829 }}
- >
- <div
- style={{ "--amount": 41829 }}
- title="41829 requests per second"
- className="BarGraphBar"
- >
- <div
- style={{ "--amount": 41829 }}
- className="BarGraphBar-label"
- >
- 41,829
- </div>
- </div>
- </div>
-
- <div
- style={{ "--amount": 2584 }}
- className="BarGraphItem BarGraphItem--node"
- >
- <div
- title="1,843 requests per second"
- style={{ "--amount": 2584 }}
- className="BarGraphBar"
- >
- <div
- style={{ "--amount": 2584 }}
- className="BarGraphBar-label"
- >
- 2,584
- </div>
- </div>
- </div>
-
- <div
- className="BarGraphItem BarGraphItem--deno"
- style={{ "--amount": 365 }}
- >
- <div
- style={{ "--amount": 365 }}
- title="365 requests per second"
- className="BarGraphBar"
- >
- <div
- style={{ "--amount": 365 }}
- className="BarGraphBar-label"
- >
- 365
- </div>
- </div>
- </div>
+ <BarGraphItem
+ type="bun"
+ amount={(115473441).toFixed(2)}
+ label="operations per second"
+ max={Math.ceil(
+ Math.max(115473441, 43478261, 2891761) * 1.25
+ )}
+ />
+ <BarGraphItem
+ type="Node-API"
+ amount={(43478261).toFixed(2)}
+ label="operations per second"
+ max={Math.ceil(
+ Math.max(115473441, 43478261, 2891761) * 1.25
+ )}
+ />
+ <BarGraphItem
+ type="deno"
+ amount={(2891761).toFixed(2)}
+ label="oeprations per iteration"
+ max={Math.ceil(
+ Math.max(115473441, 43478261, 2891761) * 1.25
+ )}
+ />
</div>
<div style={{ "--count": 3 }} className="BarGraphKey">
- <div className="BarGraphKeyItem">
- <div className="BarGraphKeyItem-label">bun.js</div>
- <div className="BarGraphKeyItem-value">v0.0.78</div>
- </div>
-
- <div className="BarGraphKeyItem">
- <div className="BarGraphKeyItem-label">node.js</div>
- <div className="BarGraphKeyItem-value">v17.7.1</div>
- </div>
-
- <div className="BarGraphKeyItem">
- <div className="BarGraphKeyItem-label">deno</div>
- <div className="BarGraphKeyItem-value">v1.20.5</div>
- </div>
+ <BarGraphLabel
+ name="bun:ffi"
+ version="v0.1.0"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.js"
+ />
+ <BarGraphLabel
+ name="node (napi)"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.node.mjs"
+ version="node v18.2.0"
+ />
+ <BarGraphLabel
+ name="deno (ffi)"
+ version="v1.23.2"
+ source="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.deno.js"
+ />
</div>
</div>
</div>
@@ -297,27 +413,33 @@ export default () => (
<ul>
<li title="npm takes 160ms to run a script that does nothing">
<Command>bun run</Command> start &nbsp;
- <code className="mono">package.json "scripts"</code> 30x faster
- than <code className="mono">npm run</code>
+ <code className="mono">package.json "scripts"</code>{" "}
+ <PerformanceClaim href="https://twitter.com/jarredsumner/status/1454218996983623685">
+ 30x faster than <code className="mono">npm run</code>
+ </PerformanceClaim>
</li>
<li title="JavaScript package managers are not using the fastest system calls">
- <Command>bun install</Command> installs npm packages up to 100x
- faster than npm, yarn or pnpm (when disk cached)
+ <Command>bun install</Command> installs npm packages 2x - 100x
+ faster than npm, yarn or pnpm
</li>
<li>
- <Command>bun dev</Command> bun's frontend dev server starts in
- about 15ms
+ <Command>bun dev</Command> bun's frontend dev server{" "}
+ <PerformanceClaim href="https://twitter.com/jarredsumner/status/1434396683861782530">
+ boots 30x faster than Create React App
+ </PerformanceClaim>
</li>
<li>
<Command>bun bun</Command> bundle node_modules into a single file
- (~1 million LOC/s input)
</li>
<li>
- <Command>bun wiptest</Command> you've never seen a JavaScript test
- runner this fast (or incomplete)
+ <Command>bun wiptest</Command>{" "}
+ <PerformanceClaim href="https://twitter.com/jarredsumner/status/1542824445810642946">
+ you've never seen a JavaScript test runner this fast
+ </PerformanceClaim>{" "}
+ (or incomplete)
</li>
</ul>
@@ -402,13 +524,13 @@ curl https://bun.sh/install | bash
<p>
{" "}
- Bun's HTTP server is built on web standards like
+ Bun's HTTP server is built on web standards like{" "}
<a
className="Identifier"
href="https://developer.mozilla.org/en-US/docs/Web/API/Request"
>
Request
- </a>
+ </a>{" "}
and{" "}
<a
className="Identifier"
@@ -506,6 +628,16 @@ export default {
<section id="explain-section">
<div id="explain"></div>
</section>
+ <script
+ dangerouslySetInnerHTML={{
+ __html: `
+[...document.querySelectorAll(".Tab")].map(el => el.addEventListener("click", function(e) {
+ var tab = e.srcElement.getAttribute("data-tab");
+ document.querySelector(".Graphs").setAttribute("class", "Graphs Graphs--active-" + tab);
+}));
+ `,
+ }}
+ />
</body>
</html>
);
diff --git a/packages/bun-landing/public/index.css b/packages/bun-landing/public/index.css
new file mode 100644
index 000000000..bd1b41e96
--- /dev/null
+++ b/packages/bun-landing/public/index.css
@@ -0,0 +1,874 @@
+:root {
+ --black: #0b0a08;
+ --blue: #00a6e1;
+ --orange: #f89b4b;
+ --orange-light: #d4d3d2;
+
+ --monospace-font: "Fira Code", "Hack", "Source Code Pro", "SF Mono",
+ "Inconsolata", monospace;
+
+ --dark-border: rgba(200, 200, 25, 0.2);
+ --max-width: 1152px;
+
+ --system-font: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI",
+ Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
+
+ --horizontal-padding: 3rem;
+ --vertical-padding: 4rem;
+ --line-height: 1.4;
+}
+* {
+ box-sizing: border-box;
+}
+head,
+body,
+:root {
+ margin: 0 auto;
+ padding: 0;
+ font-family: var(--system-font);
+}
+
+body {
+ background-color: #fbf0df;
+}
+
+a {
+ color: inherit;
+ text-decoration: none;
+ transition: transform 0.1s linear;
+}
+a:visited {
+ color: inherit;
+}
+a:hover {
+ text-decoration: underline;
+ transform: scale(1.06, 1.06);
+ transform-origin: middle center;
+}
+#header-wrap,
+#pitch {
+ background-color: var(--black);
+ color: #fbf0df;
+ width: 100%;
+}
+
+#logo-link {
+ width: fit-content;
+ display: flex;
+ gap: 24px;
+ align-items: center;
+}
+main {
+ width: auto;
+
+ margin: 0 auto;
+ max-width: var(--max-width);
+ display: grid;
+ grid-template-columns: auto auto;
+}
+
+main,
+header,
+#explain-section {
+ margin: 0 auto;
+ max-width: var(--max-width);
+ padding: 0 var(--horizontal-padding);
+}
+
+#cards-wrap,
+#usecases,
+main,
+header {
+ padding: var(--vertical-padding) var(--horizontal-padding);
+}
+
+#pitch-content {
+ max-width: 600px;
+}
+
+.tagline {
+ margin-top: 0;
+ line-height: 1;
+ font-size: 36pt;
+}
+
+.subtitle {
+ font-size: 1.2rem;
+}
+nav {
+ white-space: nowrap;
+ display: flex;
+ gap: 2rem;
+ list-style: none;
+}
+
+.NavText {
+ color: #fbf0df;
+ display: block;
+ font-weight: 500;
+ font-size: 1.2rem;
+}
+
+#HeaderInstallButton {
+ margin-left: 2.4rem;
+}
+
+#pitch main {
+ gap: 2rem;
+}
+
+#logo {
+ max-width: 70px;
+ margin: auto 0;
+}
+
+#logo-text {
+ max-width: 96px;
+}
+
+header {
+ display: grid;
+ grid-template-columns: auto max-content;
+ background-color: var(--black);
+ padding: 1.5rem 3rem;
+ align-items: center;
+ color: white;
+}
+
+#HeaderInstallButton:hover {
+ cursor: pointer;
+ transform: scale(1.06);
+}
+#HeaderInstallButton {
+ transition: transform 0.1s linear;
+ background: #00a6e1;
+ padding: 8px 16px;
+ border-radius: 100px;
+ color: black;
+ font-weight: 500;
+}
+
+.InstallBox {
+ margin-top: 2rem;
+ background: #15140e;
+ padding: 24px 24px;
+ border-radius: 24px;
+}
+
+#install-label-heading {
+ font-size: 1.4rem;
+ margin-bottom: 1rem;
+ font-weight: 500;
+ font-weight: 500;
+}
+
+#install-label-subtitle {
+ font-size: 0.9rem;
+ color: var(--orange-light);
+}
+
+.unselectable {
+ user-select: none;
+ -webkit-user-select: none;
+ -webkit-user-drag: none;
+ -moz-user-select: none;
+}
+
+#usecases-section {
+ background: linear-gradient(12deg, rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.2)),
+ conic-gradient(
+ from 6.27deg at 46.95% 50.05%,
+ #ff8181 0deg,
+ #e5f067 75deg,
+ #6dd9ba 155.62deg,
+ #67f0ae 168.75deg,
+ #8b67f0 243.75deg,
+ #f067e2 300deg,
+ #e967e3 334.49deg,
+ #f06767 348.9deg,
+ #ff8181 360deg
+ );
+ color: white;
+ font-family: var(--monospace-font);
+ contain: paint;
+
+ font-size: 24pt;
+ font-weight: bold;
+}
+
+#usecases-section {
+ padding: 0;
+ margin: 0;
+}
+
+#usecases {
+ padding-top: 1rem;
+ padding-bottom: 1rem;
+}
+
+#usecases-section h1 {
+ background: linear-gradient(90deg, #ff0000 0%, #faff00 50.52%, #0500ff 100%);
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
+ font-family: Helvetica;
+ margin: 0;
+ padding: 0;
+}
+
+#code-box {
+ background-color: rgb(37, 36, 32);
+ padding: 4px 16px;
+ position: relative;
+ border-radius: 8px;
+ text-align: center;
+ align-items: center;
+ border: 1px solid var(--orange);
+ margin-top: 1rem;
+ display: grid;
+ align-content: center;
+ white-space: nowrap;
+ margin-bottom: 1rem;
+}
+
+#code-box {
+ font-family: var(--monospace-font);
+ position: relative;
+}
+
+#curl:hover {
+ cursor: text;
+ pointer-events: auto;
+}
+
+#curl::before {
+ display: block;
+ content: "$";
+ color: var(--orange);
+ pointer-events: none;
+ width: 1ch;
+ height: 1ch;
+}
+
+#curl {
+ user-select: all;
+ -webkit-user-select: text;
+ pointer-events: auto;
+ white-space: nowrap;
+ cursor: text;
+ display: inline-flex;
+ padding: 12px 8px;
+ gap: 2ch;
+}
+
+#view-source-link {
+ color: var(--orange-light);
+}
+
+#code-box-copy {
+ position: absolute;
+ right: 16px;
+ top: 0;
+ bottom: 0;
+ height: 100%;
+
+ display: flex;
+ align-items: center;
+ z-index: 5;
+
+ color: var(--orange-light);
+ transition: transform 0.05s linear;
+ transition-property: color, transform;
+ transform-origin: center center;
+ cursor: pointer;
+}
+
+#code-box-copy:hover {
+ color: var(--blue);
+ transform: scale(1.06);
+}
+
+#code-box-copy:active {
+ transform: scale(1.12);
+}
+
+.Tabs {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr);
+ margin-left: auto;
+ margin-right: auto;
+ justify-content: center;
+ align-items: center;
+ width: min-content;
+ white-space: nowrap;
+ gap: 2rem;
+}
+
+.Tab {
+ width: min-content;
+ font-family: var(--monospace-font);
+ text-align: center;
+ padding-bottom: 8px;
+ border-bottom: 1px solid #ccc;
+ cursor: pointer;
+}
+
+.Tab[data-tab="react"]:hover,
+.Graphs--active-react .Tab[data-tab="react"],
+.Tab[data-tab="sqlite"]:hover,
+.Graphs--active-sqlite .Tab[data-tab="sqlite"],
+.Tab[data-tab="ffi"]:hover,
+.Graphs--active-ffi .Tab[data-tab="ffi"] {
+ border-bottom-color: aquamarine;
+ border-right-color: aquamarine;
+ border-left-color: aquamarine;
+}
+
+.BarGraph {
+ padding: 24px;
+ display: flex;
+ flex-direction: column;
+}
+
+.BarGraph-heading {
+ font-weight: 500;
+ font-size: 1.5rem;
+}
+
+.BarGraphList {
+ flex: 1;
+ position: relative;
+}
+.BarGraph,
+.ActiveTab,
+.Graphs {
+ height: auto;
+}
+
+.BarGraph-subheading {
+ font-size: 0.9rem;
+ color: rgb(135, 134, 134);
+}
+
+.BarGraphList {
+ margin-top: 1rem;
+ display: grid;
+ grid-template-columns: repeat(var(--count), 1fr);
+ font-variant-numeric: tabular-nums;
+ font-family: var(--monospace-font);
+ justify-content: center;
+ align-items: flex-start;
+ height: 100%;
+ background-color: #080808;
+}
+
+.BarGraphKey {
+ display: grid;
+ text-align: center;
+ margin-top: 1rem;
+ grid-template-columns: repeat(var(--count), 1fr);
+}
+
+.BarGraphBar {
+ --primary: 70px;
+ --opposite: 100%;
+}
+
+.BarGraph,
+.BarGraphBar-label,
+.BarGraphItem {
+ --level: calc(var(--amount) / var(--max));
+ --inverse: calc(1 / var(--level));
+}
+
+.BarGraphBar {
+ margin: 0 auto;
+
+ width: var(--primary);
+ height: var(--opposite);
+
+ background-color: rgb(93, 89, 134);
+ transform-origin: bottom center;
+ transform: scaleY(var(--level));
+ position: relative;
+}
+
+.BarGraphItem {
+ border-right: 1px dashed var(--dark-border);
+ border-top: 1px dashed var(--dark-border);
+ border-bottom: 1px dashed var(--dark-border);
+}
+
+.BarGraphItem--deno {
+ border-right-color: transparent;
+}
+
+.BarGraph--horizontal .BarGraphBar {
+ min-height: 200px;
+}
+
+.BarGraph--vertical .BarGraphBar {
+ max-width: 90%;
+}
+
+.BarGraphBar-label {
+ color: white;
+ font-variant-numeric: tabular-nums;
+ font-family: var(--monospace-font);
+ width: 100%;
+ text-align: center;
+
+ position: relative;
+}
+
+.CardContent {
+ position: relative;
+}
+
+.BarGraph--vertical .BarGraphBar-label {
+ transform: scaleX(var(--inverse));
+ bottom: 0;
+ right: 0;
+}
+
+.BarGraph--horizontal .BarGraphBar-label {
+ transform: scaleY(var(--inverse));
+ top: calc(-20px * var(--inverse));
+}
+
+.BarGraphItem--bun .BarGraphBar {
+ background-color: rgb(249, 241, 225);
+ box-shadow: inset 1px 1px 3px rgb(204, 198, 187);
+ background-image: url("/logo.png");
+ background-repeat: no-repeat;
+ background-size: 56px 48.8px;
+ background-position: 6px 20%;
+}
+
+.BarGraph--vertical .BarGraphItem--bun {
+ border-top-right-radius: 12px;
+ border-bottom-right-radius: 12px;
+}
+
+.BarGraph--horizontal .BarGraphItem--bun {
+ border-top-left-radius: 12px;
+ border-top-right-radius: 12px;
+}
+
+.BarGraph--vertical .BarGraphBar {
+ height: var(--primary);
+ width: var(--opposite);
+
+ transform: scaleX(var(--level));
+ transform-origin: bottom left;
+
+ max-height: 40px;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+}
+
+.BarGraph--vertical .BarGraphList,
+.BarGraph--vertical .BarGraphKey--vertical {
+ grid-template-columns: 1fr;
+ grid-template-rows: repeat(var(--count), 1fr);
+}
+
+.BarGraph--vertical .BarGraphList {
+ direction: rtl;
+}
+
+.BarGraphKeyItem-label {
+ color: white;
+}
+
+.BarGraphKeyItem-value {
+ color: #666;
+ margin-top: 0.5rem;
+}
+
+.BarGraphKeyItem-viewSource {
+ margin-top: 0.5rem;
+ color: #666;
+ text-transform: lowercase;
+ font-weight: thin;
+ font-size: 0.8rem;
+}
+
+.BarGraphKeyItem:hover {
+ text-decoration: none;
+}
+
+.BarGraphKeyItem:hover .BarGraphKeyItem-viewSource {
+ color: var(--orange-light);
+}
+
+.DemphasizedLabel {
+ text-transform: uppercase;
+ white-space: nowrap;
+}
+
+#frameworks {
+ display: flex;
+}
+
+.FrameworksGroup {
+ display: grid;
+ grid-template-rows: auto 40px;
+ gap: 0.5rem;
+}
+
+.DemphasizedLabel {
+ color: #666;
+ font-weight: 300;
+}
+
+.FrameworksList {
+ display: grid;
+ grid-template-columns: repeat(2, 40px);
+ gap: 3.5rem;
+ align-items: center;
+}
+
+#cards {
+ display: grid;
+}
+
+#explain-section {
+}
+#explain ul {
+ font-size: 1.2rem;
+}
+
+#explain li {
+ margin-bottom: 1rem;
+ line-height: var(--line-height);
+}
+
+.Tag {
+ --background: rgba(31, 31, 132, 0.15);
+ background-color: var(--background);
+ border-radius: 8px;
+ padding: 3px 8px;
+ color: white;
+ text-decoration: none !important;
+ display: inline-block;
+ font-family: var(--monospace-font) !important;
+}
+
+.Tag:visited {
+ color: white;
+}
+
+.mono {
+ font-family: var(--monospace-font);
+}
+
+.Tag--Command {
+ --background: #111;
+ font-weight: medium;
+ color: rgb(163, 255, 133);
+}
+
+.Tag--Command:before {
+ content: "❯";
+ color: rgba(255, 255, 255, 0.35);
+ margin-top: auto;
+ margin-bottom: auto;
+ margin-right: 1ch;
+ margin-left: 0.5ch;
+ display: inline-block;
+ transform: translateY(-1px);
+}
+
+.Tag--WebAPI {
+ --background: #29b6f6;
+ color: white;
+ box-shadow: inset -1px -1px 3px rgb(231, 187, 73);
+}
+
+.Tag--NodeJS {
+ --background: rgb(130, 172, 108);
+}
+
+.Tag--TypeScript {
+ --background: rgb(69, 119, 192);
+}
+
+.Tag--React {
+ color: rgb(130, 216, 247);
+ --background: #333;
+}
+
+.Tag--React:before {
+ color: rgba(130, 216, 247, 0.5);
+ content: "<";
+}
+
+.Tag--React:after {
+ color: rgba(130, 216, 247, 0.5);
+ content: ">";
+}
+
+.Tag--Bun {
+ --background: #ff17ff;
+}
+
+ul,
+li {
+}
+
+.mono {
+ font-family: var(--monospace-font);
+ border-radius: 6px;
+ color: rgb(0, 103, 19);
+}
+
+@media (min-width: 931px) {
+ .InstallBox--mobile {
+ display: none;
+ }
+}
+
+@media (max-width: 930px) {
+ header {
+ padding: 24px 16px;
+ }
+ .InstallBox--desktop {
+ display: none;
+ }
+
+ #logo {
+ max-width: 48px;
+ }
+
+ :root {
+ --max-width: 100%;
+ --horizontal-padding: 16px;
+ --vertical-padding: 2rem;
+ --line-height: 1.6;
+ }
+
+ main {
+ grid-template-columns: auto;
+ grid-template-rows: auto auto auto;
+ }
+
+ #explain li {
+ line-height: var(--line-height);
+ margin-bottom: 1.5rem;
+ }
+
+ ul {
+ padding: 0;
+ list-style: none;
+ }
+
+ .Tabs {
+ margin-left: 0;
+ }
+
+ .Graphs,
+ .BarGraph,
+ .BarGraphList {
+ max-width: auto;
+ }
+
+ .BarGraph {
+ padding: 24px 0;
+ }
+
+ #pitch-content {
+ max-width: auto;
+ }
+
+ #pitch main {
+ gap: 1rem;
+ }
+
+ #install {
+ margin-top: 0;
+ }
+
+ .tagline {
+ font-size: 32pt;
+ }
+
+ #logo-text,
+ #HeaderInstallButton {
+ display: none;
+ }
+}
+
+.InstallBox--mobile {
+ border-radius: 0;
+}
+
+@media (max-width: 599px) {
+ #code-box-copy {
+ display: none;
+ }
+
+ #code-box {
+ font-size: 0.8rem;
+ }
+}
+
+@media (max-width: 360px) {
+ .tagline {
+ font-size: 22pt;
+ }
+}
+
+#explain p {
+ line-height: var(--line-height);
+ font-size: 1.2rem;
+}
+
+#explain p a {
+ text-decoration: underline;
+}
+
+.Zig {
+ transform: translateY(15%);
+}
+
+.CodeBlock .shiki {
+ padding: 1rem;
+ border-radius: 8px;
+ font-family: var(--monospace-font);
+ font-size: 1rem;
+}
+
+.Identifier {
+ font-family: var(--monospace-font);
+ font-size: 1rem;
+ color: #50fa7b !important;
+ background-color: #282a36;
+ padding: 0.25rem;
+ border-radius: 8px;
+ text-decoration: none !important;
+}
+
+.PerformanceClaim {
+ text-decoration: dashed underline 2px #000 !important;
+ text-decoration-skip-ink: auto !important;
+}
+
+.BarGraph--react,
+.BarGraph--ffi,
+.BarGraph--sqlite {
+ display: none;
+}
+
+.Graphs--active-react .BarGraph--react,
+.Graphs--active-ffi .BarGraph--ffi,
+.Graphs--active-sqlite .BarGraph--sqlite {
+ display: block;
+}
+
+@media (min-width: 930px) {
+ .Graphs {
+ margin-left: auto;
+ }
+
+ .BarGraph-subheading,
+ .BarGraph-heading {
+ text-align: center;
+ }
+ .BarGraph-heading {
+ margin-bottom: 0.25rem;
+ }
+
+ .BarGraphKeyItem-label {
+ width: 130px;
+ }
+}
+
+@media (max-width: 929px) {
+ #code-box {
+ width: fit-content;
+ }
+
+ .CodeBlock .shiki {
+ padding: 24px 16px;
+ margin: calc(-1 * var(--horizontal-padding));
+ width: calc(
+ 100vw - var(--horizontal-padding) - var(--horizontal-padding) -2px
+ );
+ white-space: pre-wrap;
+ box-sizing: border-box;
+ border-radius: 0;
+ font-size: 0.8rem;
+ }
+
+ .logo-link {
+ gap: 0;
+ }
+
+ header {
+ grid-template-columns: min-content auto;
+ gap: 2rem;
+ }
+
+ .Tabs {
+ }
+
+ .tagline,
+ .subtitle,
+ .BarGraph-heading,
+ .BarGraph-subheading {
+ padding: 0 var(--horizontal-padding);
+ }
+
+ main {
+ padding-left: 0;
+ padding-right: 0;
+ text-align: left;
+ }
+
+ .InstallBox {
+ padding: 24px 16px;
+ margin-bottom: -32px;
+ }
+
+ .tagline {
+ font-size: 30pt;
+ }
+
+ .Tag--Command {
+ display: block;
+ width: fit-content;
+ margin-bottom: 1rem;
+ }
+
+ .Tabs {
+ margin: 0;
+ gap: 0rem;
+ width: 100%;
+ }
+
+ .Tab {
+ width: 100%;
+ padding-top: 16px;
+ padding-bottom: 16px;
+ }
+
+ .Tab {
+ border-bottom-color: #333;
+ }
+
+ #pitch-content {
+ max-width: 100%;
+ }
+
+ .Graphs--active-react .Tab[data-tab="react"],
+ .Graphs--active-sqlite .Tab[data-tab="sqlite"],
+ .Graphs--active-ffi .Tab[data-tab="ffi"] {
+ background-color: rgba(100, 100, 100, 0.1);
+ }
+
+ .Tabs {
+ border-top: 1px solid rgba(200, 200, 200, 0.1);
+ }
+}
diff --git a/packages/bun-landing/public/index.html b/packages/bun-landing/public/index.html
index 2f1d41e2b..5c2a8104b 100644
--- a/packages/bun-landing/public/index.html
+++ b/packages/bun-landing/public/index.html
@@ -1,181 +1,16 @@
-<!DOCTYPE html>
-<html>
- <head>
- <link rel="stylesheet" href="/index.css" />
- <script type="module" src="/index.js"></script>
- </head>
-
- <body>
- <div id="header-wrap">
- <header>
- <a href="/" id="logo-link">
- <img src="/public/logo@2x.png" alt="Bun" id="logo" />
- <img src="/public/Bun@2x.png" alt="Bun" id="logo-text" />
- </a>
-
- <nav class="Navigation">
- <li>
- <a class="NavText" href="/docs">Docs</a>
- </li>
- <li>
- <a class="NavText" href="/discord">Discord</a>
- </li>
- <li>
- <a class="NavText" href="/github">GitHub</a>
- </li>
- </nav>
- <div id="HeaderInstallButton">Install</div>
- </header>
- </div>
- <div id="pitch">
- <main>
- <div id="pitch-content">
- <h1 class="tagline">Bun is a fast all-in-one JavaScript runtime</h1>
- <p class="subtitle">
- Bundle, transpile, install and run JavaScript & TypeScript projects
- &mdash; all in Bun. Bun is a new JavaScript runtime with a native
- bundler, transpiler, task runner and npm client built-in.
- </p>
-
- <div id="install">
- <div id="install-label">
- <div class="unselectable" id="install-label-heading">
- Install Bun CLI v0.1.0 (beta)
- </div>
- <div class="unselectable" id="install-label-subtitle">
- macOS x64 &amp; Silicon, Linux x64, Windows Subsystem for Linux
- </div>
- </div>
- <div id="code-box">
- <div id="curl">curl https://bun.sh/install | bash</div>
- <div class="unselectable" id="code-box-copy">copy</div>
- </div>
- <a
- class="unselectable"
- id="view-source-link"
- target="_blank"
- href="https://bun.sh/install"
- >Show script source</a
- >
- </div>
- </div>
- <div class="Graphs">
- <div class="Tabs">
- <div class="Tab Tab--active">Bun.serve</div>
- <div class="Tab">bun:sqlite</div>
- <div class="Tab">bun:ffi</div>
- </div>
- <div class="ActiveTab">
- <div class="BarGraph BarGraph--horizontal BarGraph--dark">
- <div class="BarGraph-heading">HTTP requests per second</div>
- <div class="BarGraph-subheading">
- Serving a 47 KB file * Bigger is better
- </div>
-
- <div style="--count: 3" class="BarGraphList">
- <div
- class="BarGraphItem BarGraphItem--bun"
- style="--amount: 41829"
- >
- <div
- style="--amount: 41829"
- title="41829 requests per second"
- class="BarGraphBar"
- >
- <div style="--amount: 41829" class="BarGraphBar-label">
- 41,829
- </div>
- </div>
- </div>
-
- <div
- style="--amount: 2584"
- class="BarGraphItem BarGraphItem--node"
- >
- <div
- title="1,843 requests per second"
- style="--amount: 2584"
- class="BarGraphBar"
- >
- <div style="--amount: 2584" class="BarGraphBar-label">
- 2,584
- </div>
- </div>
- </div>
-
- <div
- class="BarGraphItem BarGraphItem--deno"
- style="--amount: 365"
- >
- <div
- style="--amount: 365"
- title="365 requests per second"
- class="BarGraphBar"
- >
- <div style="--amount: 365" class="BarGraphBar-label">
- 365
- </div>
- </div>
- </div>
- </div>
-
- <div style="--count: 3" class="BarGraphKey">
- <div class="BarGraphKeyItem">
- <div class="BarGraphKeyItem-label">bun.js</div>
- <div class="BarGraphKeyItem-value">v0.0.78</div>
- </div>
-
- <div class="BarGraphKeyItem">
- <div class="BarGraphKeyItem-label">node.js</div>
- <div class="BarGraphKeyItem-value">v17.7.1</div>
- </div>
-
- <div class="BarGraphKeyItem">
- <div class="BarGraphKeyItem-label">deno</div>
- <div class="BarGraphKeyItem-value">v1.20.5</div>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <!-- <div id="frameworks">
- <div class="FrameworksGroup">
- <div class="DemphasizedLabel">Supported frameworks</div>
- <div class="FrameworksList">
- <a
- referrerpolicy="no-referrer"
- class="Framework"
- href="https://nextjs.org"
- target="_blank"
- ><img
- src="/public/next.svg"
- height="40"
- alt="Next.js"
- decoding="async"
- /></a>
- <a
- class="Framework"
- referrerpolicy="no-referrer"
- href="https://remix.run"
- target="_blank"
- >
- <img
- src="/public/remix.svg"
- alt="Remix"
- height="26"
- decoding="async"
- />
- </a>
- </div>
- </div>
- </div> -->
- </main>
- </div>
- <section id="explain-section">
- <div id="explain">
- <h1>Getting started</h1>
- </div>
- </section>
- </body>
-</html>
+<!DOCTYPE html><html><head><link rel="stylesheet" href="/index.css"/><script type="module" src="/index.js"></script><meta name="viewport" content="width=device-width, initial-scale=1"/></head><body><div id="header-wrap"><header><a href="/" id="logo-link"><img src="/logo@2x.png" alt="Bun" id="logo"/><img src="/Bun@2x.png" alt="Bun" id="logo-text"/></a><nav class="Navigation"><li><a class="NavText" href="/docs">Docs</a></li><li><a class="NavText" href="/discord">Discord</a></li><li><a class="NavText" href="/github">GitHub</a></li></nav></header></div><div id="pitch"><main><div id="pitch-content"><h1 class="tagline">Bun is a fast all-in-one JavaScript runtime</h1><p class="subtitle">Bundle, transpile, install and run JavaScript &amp; TypeScript projects — all in Bun. Bun is a new JavaScript runtime with a native bundler, transpiler, task runner and npm client built-in.</p><div class="InstallBox InstallBox--desktop" id="install"><div id="install-label"><div class="unselectable" id="install-label-heading">Install Bun CLI v0.1.0 (beta)</div><div class="unselectable" id="install-label-subtitle">macOS x64 &amp; Silicon, Linux x64, Windows Subsystem for Linux</div></div><div id="code-box"><div id="curl">curl https://bun.sh/install | bash</div><div class="unselectable" id="code-box-copy">copy</div></div><a class="unselectable" id="view-source-link" target="_blank" href="https://bun.sh/install">Show script source</a></div></div><div class="Graphs Graphs--active-react"><div class="Tabs"><div data-tab="react" class="Tab">Bun.serve</div><div data-tab="sqlite" class="Tab">bun:sqlite</div><div data-tab="ffi" class="Tab">bun:ffi</div></div><div id="active-tab" class="ActiveTab"><div class="BarGraph BarGraph--react BarGraph--horizontal BarGraph--dark"><div class="BarGraph-heading">Server-side rendering React</div><div title="oha -z 5s" class="BarGraph-subheading">HTTP requests per second (Linux AMD64)</div><div style="--count:3" class="BarGraphList"><div class="BarGraphItem BarGraphItem--bun" style="--amount:48936;--max:61170"><div style="--amount:48936;--max:61170" title="48936 requests per second" class="BarGraphBar"><div style="--amount:48936;--max:61170" class="BarGraphBar-label">48,936</div></div></div><div class="BarGraphItem BarGraphItem--node" style="--amount:16288;--max:61170"><div style="--amount:16288;--max:61170" title="16288 requests per second" class="BarGraphBar"><div style="--amount:16288;--max:61170" class="BarGraphBar-label">16,288</div></div></div><div class="BarGraphItem BarGraphItem--deno" style="--amount:12289;--max:61170"><div style="--amount:12289;--max:61170" title="12289 requests per second" class="BarGraphBar"><div style="--amount:12289;--max:61170" class="BarGraphBar-label">12,289</div></div></div></div><div style="--count:3" class="BarGraphKey"><a href="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.jsx" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">bun</div><div class="BarGraphKeyItem-value">v0.1.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.deno.jsx" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">node</div><div class="BarGraphKeyItem-value">v18.1.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/bench/react-hello-world.node.jsx" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">deno</div><div class="BarGraphKeyItem-value">v1.23.2</div><div class="BarGraphKeyItem-viewSource">View source</div></a></div></div><div class="BarGraph--sqlite BarGraph BarGraph--horizontal BarGraph--dark"><div class="BarGraph-heading">Average queries per second<!-- --> <!-- --></div><div class="BarGraph-subheading">SELECT * from &quot;Orders&quot; (Northwind Traders)</div><div style="--count:3" class="BarGraphList"><div class="BarGraphItem BarGraphItem--bun" style="--amount:60.24;--max:76"><div style="--amount:60.24;--max:76" title="60.24 queries per second" class="BarGraphBar"><div style="--amount:60.24;--max:76" class="BarGraphBar-label">60.24</div></div></div><div class="BarGraphItem BarGraphItem--better-sqlite3" style="--amount:23.28;--max:76"><div style="--amount:23.28;--max:76" title="23.28 queries per second" class="BarGraphBar"><div style="--amount:23.28;--max:76" class="BarGraphBar-label">23.28</div></div></div><div class="BarGraphItem BarGraphItem--deno" style="--amount:9.55;--max:76"><div style="--amount:9.55;--max:76" title="9.55 queries per second" class="BarGraphBar"><div style="--amount:9.55;--max:76" class="BarGraphBar-label">9.55</div></div></div></div><div style="--count:3" class="BarGraphKey"><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.js" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">bun:sqlite</div><div class="BarGraphKeyItem-value">v0.1.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.node.mjs" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">better-sqlite3</div><div class="BarGraphKeyItem-value">node v18.2.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.deno.js" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">deno (x/sqlite)</div><div class="BarGraphKeyItem-value">v1.23.2</div><div class="BarGraphKeyItem-viewSource">View source</div></a></div></div><div class="BarGraph BarGraph--ffi BarGraph--horizontal BarGraph--dark"><div class="BarGraph-heading">Operations per second</div><div class="BarGraph-subheading">Call add(1,2,3) from JavaScript</div><div style="--count:3" class="BarGraphList"><div class="BarGraphItem BarGraphItem--bun" style="--amount:115473441.00;--max:144341802"><div style="--amount:115473441.00;--max:144341802" title="115473441.00 operations per second" class="BarGraphBar"><div style="--amount:115473441.00;--max:144341802" class="BarGraphBar-label">115,473,441</div></div></div><div class="BarGraphItem BarGraphItem--Node-API" style="--amount:43478261.00;--max:144341802"><div style="--amount:43478261.00;--max:144341802" title="43478261.00 operations per second" class="BarGraphBar"><div style="--amount:43478261.00;--max:144341802" class="BarGraphBar-label">43,478,261</div></div></div><div class="BarGraphItem BarGraphItem--deno" style="--amount:2891761.00;--max:144341802"><div style="--amount:2891761.00;--max:144341802" title="2891761.00 oeprations per iteration" class="BarGraphBar"><div style="--amount:2891761.00;--max:144341802" class="BarGraphBar-label">2,891,761</div></div></div></div><div style="--count:3" class="BarGraphKey"><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.js" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">bun:ffi</div><div class="BarGraphKeyItem-value">v0.1.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.node.mjs" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">node (napi)</div><div class="BarGraphKeyItem-value">node v18.2.0</div><div class="BarGraphKeyItem-viewSource">View source</div></a><a href="https://github.com/Jarred-Sumner/bun/blob/main/bench/sqlite/query.deno.js" target="_blank" class="BarGraphKeyItem"><div class="BarGraphKeyItem-label">deno (ffi)</div><div class="BarGraphKeyItem-value">v1.23.2</div><div class="BarGraphKeyItem-viewSource">View source</div></a></div></div></div></div><div class="InstallBox InstallBox--mobile" id="install"><div id="install-label"><div class="unselectable" id="install-label-heading">Install Bun CLI v0.1.0 (beta)</div><div class="unselectable" id="install-label-subtitle">macOS x64 &amp; Silicon, Linux x64, Windows Subsystem for Linux</div></div><div id="code-box"><div id="curl">curl https://bun.sh/install | bash</div><div class="unselectable" id="code-box-copy">copy</div></div><a class="unselectable" id="view-source-link" target="_blank" href="https://bun.sh/install">Show script source</a></div></main></div><section id="explain-section"><div id="explain"><h1>🐚 All the tools</h1><ul><li title="npm takes 160ms to run a script that does nothing"><span target="_blank" class="Tag Tag--Command">bun run</span> start  <!-- --><code class="mono">package.json &quot;scripts&quot;</code> <!-- --><a href="https://twitter.com/jarredsumner/status/1454218996983623685" target="_blank" class="PerformanceClaim">30x faster than <!-- --><code class="mono">npm run</code></a></li><li title="JavaScript package managers are not using the fastest system calls"><span target="_blank" class="Tag Tag--Command">bun install</span> installs npm packages 2x - 100x faster than npm, yarn or pnpm<!-- --></li><li><span target="_blank" class="Tag Tag--Command">bun dev</span> bun&#x27;s frontend dev server<!-- --> <!-- --><a href="https://twitter.com/jarredsumner/status/1434396683861782530" target="_blank" class="PerformanceClaim">boots 30x faster than Create React App</a></li><li><span target="_blank" class="Tag Tag--Command">bun bun</span> bundle node_modules into a single file<!-- --></li><li><span target="_blank" class="Tag Tag--Command">bun wiptest</span> <!-- --><a href="https://twitter.com/jarredsumner/status/1542824445810642946" target="_blank" class="PerformanceClaim">you&#x27;ve never seen a JavaScript test runner this fast</a> <!-- -->(or incomplete)<!-- --></li></ul><h1>🔋 Batteries included</h1><ul><li>Web APIs like<!-- --> <!-- --><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/fetch" class="Tag Tag--WebAPI">fetch</a>,<!-- --> <!-- --><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket" class="Tag Tag--WebAPI">WebSocket</a>, and<!-- --> <!-- --><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream" class="Tag Tag--WebAPI">ReadableStream</a> <!-- -->are builtin<!-- --></li><li><span target="_blank" class="Tag Tag--NodeJS">node_modules</span> bun implements Node.js&#x27; module resolution algorithm, so you can use npm packages in bun.js. ESM and CommonJS are supported, but Bun internally uses ESM.<!-- --></li><li><span target="_blank" class="Tag Tag--React">JSX</span> <!-- --><span target="_blank" class="Tag Tag--TypeScript">TypeScript</span> in bun.js, every file is transpiled. TypeScript &amp; JSX just work.<!-- --></li><li><span target="_blank" class="Tag Tag--TypeScript">tsconfig.json</span> bun supports<!-- --> <!-- --><code class="">&quot;paths&quot;</code>, <!-- --><code>&quot;jsxImportSource&quot;</code>and more from tsconfig.json<!-- --></li><li><span target="_blank" class="Tag Tag--Bun">Bun.Transpiler</span> bun&#x27;s JSX &amp; TypeScript transpiler is available as an API in Bun.js<!-- --></li><li><span target="_blank" class="Tag Tag--Bun">Bun.write</span> use the fastest system calls available to write, copy, pipe, send and clone files.<!-- --></li><li><span target="_blank" class="Tag Tag--Bun">.env</span> bun.js automatically loads environment variables from .env files. No more<!-- --> <!-- --><code class="mono">require(&quot;dotenv&quot;).load()</code></li><li><span target="_blank" class="Tag Tag--Bun">bun:sqlite</span> fast SQLite3 client built-in<!-- --></li><li><a target="_blank" href="https://github.com/Jarred-Sumner/bun/issues/158" class="Tag Tag--NodeJS">Node-API</a> <!-- -->bun.js implements most of Node-API (NAPI). Many Node.js native modules just work.<!-- --></li><li><span target="_blank" class="Tag Tag--Bun">bun:ffi</span> call native code from JavaScript with bun&#x27;s low-overhead foreign function interface<!-- --></li><li><span target="_blank" class="Tag Tag--NodeJS">node:fs</span> <!-- --><span target="_blank" class="Tag Tag--NodeJS">node:path</span> bun.js natively supports a growing list of Node.js core modules along with globals like Buffer and process.<!-- --></li></ul><h1>Getting started</h1><p>To install bun, run this<!-- --> <!-- --><a target="_blank" href="https://bun.sh/install">install script</a> <!-- -->in your terminal. It downloads Bun from GitHub.<!-- --></p><div class="CodeBlock"><pre class="shiki" style="background-color: #282A36"><code><span class="line"><span style="color: #F8F8F2">curl https://bun.sh/install </span><span style="color: #FF79C6">|</span><span style="color: #F8F8F2"> bash</span></span></code></pre></div><p> <!-- -->Bun&#x27;s HTTP server is built on web standards like<!-- --> <!-- --><a class="Identifier" href="https://developer.mozilla.org/en-US/docs/Web/API/Request">Request</a> <!-- -->and<!-- --> <!-- --><a class="Identifier" href="https://developer.mozilla.org/en-US/docs/Web/API/Response">Response</a></p><div class="CodeBlock"><pre class="shiki" style="background-color: #282A36"><code><span class="line"><span style="color: #6272A4">// http.js</span></span>
+<span class="line"><span style="color: #FF79C6">export</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">default</span><span style="color: #F8F8F2"> {</span></span>
+<span class="line"><span style="color: #F8F8F2"> port</span><span style="color: #FF79C6">:</span><span style="color: #F8F8F2"> </span><span style="color: #BD93F9">3000</span><span style="color: #F8F8F2">,</span></span>
+<span class="line"><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">fetch</span><span style="color: #F8F8F2">(</span><span style="color: #FFB86C; font-style: italic">request</span><span style="color: #F8F8F2">) {</span></span>
+<span class="line"><span style="color: #F8F8F2"> </span><span style="color: #FF79C6">return</span><span style="color: #F8F8F2"> </span><span style="color: #FF79C6; font-weight: bold">new</span><span style="color: #F8F8F2"> </span><span style="color: #50FA7B">Response</span><span style="color: #F8F8F2">(</span><span style="color: #E9F284">&quot;</span><span style="color: #F1FA8C">Welcome to Bun!</span><span style="color: #E9F284">&quot;</span><span style="color: #F8F8F2">);</span></span>
+<span class="line"><span style="color: #F8F8F2"> },</span></span>
+<span class="line"><span style="color: #F8F8F2">};</span></span></code></pre></div><p>Run it with bun:</p><div class="CodeBlock"><pre class="shiki" style="background-color: #282A36"><code><span class="line"><span style="color: #F8F8F2">bun run http.js</span></span></code></pre></div><p>Then open<!-- --> <!-- --><a target="_blank" href="http://localhost:3000">http://localhost:3000</a> <!-- -->in your browser<!-- --><br/><br/>See<!-- --> <!-- --><a href="https://github.com/Jarred-Sumner/bun/tree/main/examples">more examples</a> <!-- -->and check out <!-- --><a href="/docs">the docs</a>. If you have any questions or want help, join<!-- --> <!-- --><a href="https://bun.sh/discord">Bun&#x27;s Discord</a></p><h1>How does Bun work?</h1><p>Bun.js uses the<!-- --> <!-- --><a href="https://github.com/WebKit/WebKit/tree/main/Source/JavaScriptCore">JavaScriptCore</a> <!-- -->engine, which tends<!-- --> <!-- --><a target="blank" href="https://twitter.com/jarredsumner/status/1499225725492076544">to start</a> <!-- -->and perform a little faster than more traditional choices like V8. Bun is written in<!-- --> <!-- --><a href="https://ziglang.org/"><svg xmlns="http://www.w3.org/2000/svg" height="1.2rem" class="Zig" viewBox="0 0 400 140"><g fill="#F7A41D"><g><polygon points="46,22 28,44 19,30"></polygon><polygon points="46,22 33,33 28,44 22,44 22,95 31,95 20,100 12,117 0,117 0,22" shape-rendering="crispEdges"></polygon><polygon points="31,95 12,117 4,106"></polygon></g><g><polygon points="56,22 62,36 37,44"></polygon><polygon points="56,22 111,22 111,44 37,44 56,32" shape-rendering="crispEdges"></polygon><polygon points="116,95 97,117 90,104"></polygon><polygon points="116,95 100,104 97,117 42,117 42,95" shape-rendering="crispEdges"></polygon><polygon points="150,0 52,117 3,140 101,22"></polygon></g><g><polygon points="141,22 140,40 122,45"></polygon><polygon points="153,22 153,117 106,117 120,105 125,95 131,95 131,45 122,45 132,36 141,22" shape-rendering="crispEdges"></polygon><polygon points="125,95 130,110 106,117"></polygon></g></g><g fill="#121212"><g><polygon points="260,22 260,37 229,40 177,40 177,22" shape-rendering="crispEdges"></polygon><polygon points="260,37 207,99 207,103 176,103 229,40 229,37"></polygon><polygon points="261,99 261,117 176,117 176,103 206,99" shape-rendering="crispEdges"></polygon></g><rect x="272" y="22" shape-rendering="crispEdges" width="22" height="95"></rect><g><polygon points="394,67 394,106 376,106 376,81 360,70 346,67" shape-rendering="crispEdges"></polygon><polygon points="360,68 376,81 346,67"></polygon><path d="M394,106c-10.2,7.3-24,12-37.7,12c-29,0-51.1-20.8-51.1-48.3c0-27.3,22.5-48.1,52-48.1
+ c14.3,0,29.2,5.5,38.9,14l-13,15c-7.1-6.3-16.8-10-25.9-10c-17,0-30.2,12.9-30.2,29.5c0,16.8,13.3,29.6,30.3,29.6
+ c5.7,0,12.8-2.3,19-5.5L394,106z"></path></g></g></svg></a>, a low-level programming language with manual memory management.<!-- --><br/><br/>Most of Bun is written from scratch including the JSX/TypeScript transpiler, npm client, bundler, SQLite client, HTTP client, WebSocket client and more.<!-- --></p><h1>Why is Bun fast?</h1><p>An enourmous amount of time spent profiling, benchmarking and optimizing things. The answer is different for every part of Bun, but one general theme:<!-- --> <!-- --><a href="https://ziglang.org/"><svg xmlns="http://www.w3.org/2000/svg" height="1.2rem" class="Zig" viewBox="0 0 400 140"><g fill="#F7A41D"><g><polygon points="46,22 28,44 19,30"></polygon><polygon points="46,22 33,33 28,44 22,44 22,95 31,95 20,100 12,117 0,117 0,22" shape-rendering="crispEdges"></polygon><polygon points="31,95 12,117 4,106"></polygon></g><g><polygon points="56,22 62,36 37,44"></polygon><polygon points="56,22 111,22 111,44 37,44 56,32" shape-rendering="crispEdges"></polygon><polygon points="116,95 97,117 90,104"></polygon><polygon points="116,95 100,104 97,117 42,117 42,95" shape-rendering="crispEdges"></polygon><polygon points="150,0 52,117 3,140 101,22"></polygon></g><g><polygon points="141,22 140,40 122,45"></polygon><polygon points="153,22 153,117 106,117 120,105 125,95 131,95 131,45 122,45 132,36 141,22" shape-rendering="crispEdges"></polygon><polygon points="125,95 130,110 106,117"></polygon></g></g><g fill="#121212"><g><polygon points="260,22 260,37 229,40 177,40 177,22" shape-rendering="crispEdges"></polygon><polygon points="260,37 207,99 207,103 176,103 229,40 229,37"></polygon><polygon points="261,99 261,117 176,117 176,103 206,99" shape-rendering="crispEdges"></polygon></g><rect x="272" y="22" shape-rendering="crispEdges" width="22" height="95"></rect><g><polygon points="394,67 394,106 376,106 376,81 360,70 346,67" shape-rendering="crispEdges"></polygon><polygon points="360,68 376,81 346,67"></polygon><path d="M394,106c-10.2,7.3-24,12-37.7,12c-29,0-51.1-20.8-51.1-48.3c0-27.3,22.5-48.1,52-48.1
+ c14.3,0,29.2,5.5,38.9,14l-13,15c-7.1-6.3-16.8-10-25.9-10c-17,0-30.2,12.9-30.2,29.5c0,16.8,13.3,29.6,30.3,29.6
+ c5.7,0,12.8-2.3,19-5.5L394,106z"></path></g></g></svg></a> <!-- -->&#x27;s low-level control over memory and lack of hidden control flow makes it much simpler to write fast software.<!-- --> <!-- --><a href="https://github.com/sponsors/ziglang">Sponsor the Zig Software Foundation</a></p><h1>What is the license?</h1><p>MIT License, excluding dependencies which have various licenses.</p><h1>How do I see the source code?</h1><p>Bun is on <!-- --><a href="https://github.com/Jarred-Sumner/bun">GitHub</a></p></div></section><section id="explain-section"><div id="explain"></div></section><script>
+[...document.querySelectorAll(".Tab")].map(el => el.addEventListener("click", function(e) {
+ var tab = e.srcElement.getAttribute("data-tab");
+ document.querySelector(".Graphs").setAttribute("class", "Graphs Graphs--active-" + tab);
+}));
+ </script></body></html> \ No newline at end of file
diff --git a/packages/bun-landing/ssr.tsx b/packages/bun-landing/ssr.tsx
index cb1c6c429..a608f968e 100644
--- a/packages/bun-landing/ssr.tsx
+++ b/packages/bun-landing/ssr.tsx
@@ -1,7 +1,6 @@
-import React from "react";
import { file, serve } from "bun";
-
-import { renderToReadableStream } from "./react-dom-server.bun.production.min";
+import "shiki";
+import { renderToReadableStream } from "../../test/bun.js/reactdom-bun";
import liveReload from "bun-livereload";
import { join } from "path";
@@ -12,7 +11,7 @@ async function fetch(req: Request) {
}
if (!req.url.includes(".")) {
- const { default: Page } = await import("./page.jsx");
+ const { default: Page } = await import("./page.tsx");
return new Response(await renderToReadableStream(<Page />), {
headers: {
"Content-Type": "text/html",
@@ -20,9 +19,12 @@ async function fetch(req: Request) {
});
}
- return new Response(file(join(import.meta.dir, new URL(req.url).pathname)));
+ return new Response(
+ file(join(import.meta.dir, "./public/", new URL(req.url).pathname))
+ );
}
serve({
fetch: liveReload(fetch),
+ port: 8080,
});