diff options
author | 2022-07-05 02:25:33 -0700 | |
---|---|---|
committer | 2022-07-05 02:25:33 -0700 | |
commit | 2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9 (patch) | |
tree | 1f8060994a8027d7a8ec7de7a770dc763d9d3f08 | |
parent | 2d8dfeff49a543054e9390c505337386aaf1cd9b (diff) | |
download | bun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.tar.gz bun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.tar.zst bun-2470c0d090d135f3d6e6ab11ae739e0fb7bca5c9.zip |
Current landing
-rw-r--r-- | packages/bun-landing/build.tsx | 15 | ||||
-rw-r--r-- | packages/bun-landing/index.css | 166 | ||||
-rw-r--r-- | packages/bun-landing/page.tsx | 312 | ||||
-rw-r--r-- | packages/bun-landing/public/index.css | 874 | ||||
-rw-r--r-- | packages/bun-landing/public/index.html | 197 | ||||
-rw-r--r-- | packages/bun-landing/ssr.tsx | 12 |
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 - <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 - — 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 & 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 & 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 & 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 "Orders" (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 & 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 "scripts"</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'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'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' 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 & JSX just work.<!-- --></li><li><span target="_blank" class="Tag Tag--TypeScript">tsconfig.json</span> bun supports<!-- --> <!-- --><code class="">"paths"</code>, <!-- --><code>"jsxImportSource"</code>and more from tsconfig.json<!-- --></li><li><span target="_blank" class="Tag Tag--Bun">Bun.Transpiler</span> bun's JSX & 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("dotenv").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'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'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">"</span><span style="color: #F1FA8C">Welcome to Bun!</span><span style="color: #E9F284">"</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'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> <!-- -->'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, }); |