diff --git a/.buildkite/Dockerfile b/.buildkite/Dockerfile
index 55e45ccdff..033aec633d 100644
--- a/.buildkite/Dockerfile
+++ b/.buildkite/Dockerfile
@@ -133,6 +133,20 @@ RUN ARCH=$(if [ "$TARGETARCH" = "arm64" ]; then echo "arm64"; else echo "amd64";
RUN mkdir -p /var/cache/buildkite-agent /var/log/buildkite-agent /var/run/buildkite-agent /etc/buildkite-agent /var/lib/buildkite-agent/cache/bun
+# The following is necessary to configure buildkite to use a stable
+# checkout directory. sccache hashes absolute paths into its cache keys,
+# so if buildkite uses a different checkout path each time (which it does
+# by default), sccache will be useless.
+RUN mkdir -p -m 755 /var/lib/buildkite-agent/hooks && \
+ cat <<'EOF' > /var/lib/buildkite-agent/hooks/environment
+#!/bin/sh
+set -efu
+
+export BUILDKITE_BUILD_CHECKOUT_PATH=/var/lib/buildkite-agent/build
+EOF
+
+RUN chmod 744 /var/lib/buildkite-agent/hooks/environment
+
COPY ../*/agent.mjs /var/bun/scripts/
ENV BUN_INSTALL_CACHE=/var/lib/buildkite-agent/cache/bun
diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml
index e949cf9b41..cc10727b59 100644
--- a/.github/workflows/format.yml
+++ b/.github/workflows/format.yml
@@ -9,7 +9,7 @@ on:
pull_request:
merge_group:
env:
- BUN_VERSION: "1.2.20"
+ BUN_VERSION: "1.3.2"
LLVM_VERSION: "19.1.7"
LLVM_VERSION_MAJOR: "19"
diff --git a/README.md b/README.md
index 61733ac8e8..3c845722d1 100644
--- a/README.md
+++ b/README.md
@@ -230,7 +230,7 @@ bun upgrade --canary
- Ecosystem
- [Use React and JSX](https://bun.com/guides/ecosystem/react)
- - [Use EdgeDB with Bun](https://bun.com/guides/ecosystem/edgedb)
+ - [Use Gel with Bun](https://bun.com/guides/ecosystem/gel)
- [Use Prisma with Bun](https://bun.com/guides/ecosystem/prisma)
- [Add Sentry to a Bun app](https://bun.com/guides/ecosystem/sentry)
- [Create a Discord bot](https://bun.com/guides/ecosystem/discordjs)
diff --git a/bun.lock b/bun.lock
index 6a66c586b2..e3d7fb8ecd 100644
--- a/bun.lock
+++ b/bun.lock
@@ -1,5 +1,6 @@
{
"lockfileVersion": 1,
+ "configVersion": 0,
"workspaces": {
"": {
"name": "bun",
diff --git a/cmake/tools/SetupSccache.cmake b/cmake/tools/SetupSccache.cmake
index 6736f0706e..cb4b5aa750 100644
--- a/cmake/tools/SetupSccache.cmake
+++ b/cmake/tools/SetupSccache.cmake
@@ -10,12 +10,8 @@ set(SCCACHE_SHARED_CACHE_BUCKET "bun-build-sccache-store")
function(check_aws_credentials OUT_VAR)
# Install dependencies first
execute_process(
- COMMAND
- ${BUN_EXECUTABLE}
- install
- --frozen-lockfile
- WORKING_DIRECTORY
- ${CMAKE_SOURCE_DIR}/scripts/build-cache
+ COMMAND ${BUN_EXECUTABLE} install --frozen-lockfile
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/scripts/build-cache
RESULT_VARIABLE INSTALL_EXIT_CODE
OUTPUT_VARIABLE INSTALL_OUTPUT
ERROR_VARIABLE INSTALL_ERROR
@@ -106,26 +102,22 @@ function(sccache_configure_environment_developer)
endif()
endfunction()
-function(sccache_configure)
- find_command(VARIABLE SCCACHE_PROGRAM COMMAND sccache REQUIRED ${CI})
- if(NOT SCCACHE_PROGRAM)
- message(WARNING "sccache not found. Your builds will be slower.")
- return()
- endif()
+find_command(VARIABLE SCCACHE_PROGRAM COMMAND sccache REQUIRED ${CI})
+if(NOT SCCACHE_PROGRAM)
+ message(WARNING "sccache not found. Your builds will be slower.")
+ return()
+endif()
- set(SCCACHE_ARGS CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER)
- foreach(arg ${SCCACHE_ARGS})
- setx(${arg} ${SCCACHE_PROGRAM})
- list(APPEND CMAKE_ARGS -D${arg}=${${arg}})
- endforeach()
+set(SCCACHE_ARGS CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER)
+foreach(arg ${SCCACHE_ARGS})
+ setx(${arg} ${SCCACHE_PROGRAM})
+ list(APPEND CMAKE_ARGS -D${arg}=${${arg}})
+endforeach()
- setenv(SCCACHE_LOG "info")
+setenv(SCCACHE_LOG "info")
- if (CI)
- sccache_configure_environment_ci()
- else()
- sccache_configure_environment_developer()
- endif()
-endfunction()
-
-sccache_configure()
+if (CI)
+ sccache_configure_environment_ci()
+else()
+ sccache_configure_environment_developer()
+endif()
diff --git a/docs/bundler/executables.mdx b/docs/bundler/executables.mdx
index af2229227e..79e6d6a55e 100644
--- a/docs/bundler/executables.mdx
+++ b/docs/bundler/executables.mdx
@@ -216,7 +216,7 @@ However, with the `BUN_BE_BUN=1` environment variable, it acts just like the `bu
```bash icon="terminal" terminal
# With the env var, the executable acts like the `bun` CLI
-bun_BE_BUN=1 ./such-bun install
+BUN_BE_BUN=1 ./such-bun install
```
```txt
diff --git a/docs/bundler/html-static.mdx b/docs/bundler/html-static.mdx
index 8dd8ecb955..135b7f41ac 100644
--- a/docs/bundler/html-static.mdx
+++ b/docs/bundler/html-static.mdx
@@ -237,13 +237,27 @@ Then, reference TailwindCSS in your HTML via `` tag, `@import` in CSS, or
+
```html title="index.html" icon="file-code"
- {/* Reference TailwindCSS in your HTML */}
+
```
+
+
+
+
+ ```css title="styles.css" icon="file-code"
+ @import "tailwindcss";
+ ```
+
+
+
+
+ ```ts title="app.ts" icon="/icons/typescript.svg"
+ import "tailwindcss";
+ ```
+
- ```css title="styles.css" icon="file-code" @import "tailwindcss"; ```
- ```ts title="app.ts" icon="/icons/typescript.svg" import "tailwindcss"; ```Only one of those are necessary, not all three.
diff --git a/docs/bundler/loaders.mdx b/docs/bundler/loaders.mdx
index 89e8824679..bb55a49675 100644
--- a/docs/bundler/loaders.mdx
+++ b/docs/bundler/loaders.mdx
@@ -11,10 +11,12 @@ The Bun bundler implements a set of default loaders out of the box.
Bun uses the file extension to determine which built-in loader should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building plugins that extend Bun with custom loaders.
-You can explicitly specify which loader to use using the `'loader'` import attribute.
+You can explicitly specify which loader to use using the `'type'` import attribute.
```ts title="index.ts" icon="/icons/typescript.svg"
-import my_toml from "./my_file" with { loader: "toml" };
+import my_toml from "./my_file" with { type: "toml" };
+// or with dynamic imports
+const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });
```
## Built-in loaders
@@ -117,8 +119,7 @@ var config = {
```
- Bun automatically uses the `jsonc` loader for `tsconfig.json`, `jsconfig.json`, `package.json`, and `bun.lock` files,
- allowing comments and trailing commas in these files.
+ Bun automatically uses the `jsonc` loader for `tsconfig.json`, `jsconfig.json`, `package.json`, and `bun.lock` files.
---
diff --git a/docs/docs.json b/docs/docs.json
index 38fd681f92..cfb3924cc3 100644
--- a/docs/docs.json
+++ b/docs/docs.json
@@ -354,7 +354,7 @@
"/guides/ecosystem/discordjs",
"/guides/ecosystem/docker",
"/guides/ecosystem/drizzle",
- "/guides/ecosystem/edgedb",
+ "/guides/ecosystem/gel",
"/guides/ecosystem/elysia",
"/guides/ecosystem/express",
"/guides/ecosystem/hono",
diff --git a/docs/guides/ecosystem/edgedb.mdx b/docs/guides/ecosystem/gel.mdx
similarity index 63%
rename from docs/guides/ecosystem/edgedb.mdx
rename to docs/guides/ecosystem/gel.mdx
index 6b621f9139..c26a6bfa64 100644
--- a/docs/guides/ecosystem/edgedb.mdx
+++ b/docs/guides/ecosystem/gel.mdx
@@ -1,23 +1,27 @@
---
-title: Use EdgeDB with Bun
-sidebarTitle: EdgeDB with Bun
+title: Use Gel with Bun
+sidebarTitle: Gel with Bun
mode: center
---
-EdgeDB is a graph-relational database powered by Postgres under the hood. It provides a declarative schema language, migrations system, and object-oriented query language, in addition to supporting raw SQL queries. It solves the object-relational mapping problem at the database layer, eliminating the need for an ORM library in your application code.
+Gel (formerly EdgeDB) is a graph-relational database powered by Postgres under the hood. It provides a declarative schema language, migrations system, and object-oriented query language, in addition to supporting raw SQL queries. It solves the object-relational mapping problem at the database layer, eliminating the need for an ORM library in your application code.
---
-First, [install EdgeDB](https://www.edgedb.com/install) if you haven't already.
+First, [install Gel](https://docs.geldata.com/learn/installation) if you haven't already.
```sh Linux/macOS terminal icon="terminal"
-curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh
+curl https://www.geldata.com/sh --proto "=https" -sSf1 | sh
```
```sh Windows terminal icon="windows"
-iwr https://ps1.edgedb.com -useb | iex
+irm https://www.geldata.com/ps1 | iex
+```
+
+```sh Homebrew terminal icon="terminal"
+brew install geldata/tap/gel-cli
```
@@ -34,35 +38,35 @@ bun init -y
---
-We'll use the EdgeDB CLI to initialize an EdgeDB instance for our project. This creates an `edgedb.toml` file in our project root.
+We'll use the Gel CLI to initialize a Gel instance for our project. This creates a `gel.toml` file in our project root.
```sh terminal icon="terminal"
-edgedb project init
+gel project init
```
```txt
-No `edgedb.toml` found in `/Users/colinmcd94/Documents/bun/fun/examples/my-edgedb-app` or above
+No `gel.toml` found in `/Users/colinmcd94/Documents/bun/fun/examples/my-gel-app` or above
Do you want to initialize a new project? [Y/n]
> Y
-Specify the name of EdgeDB instance to use with this project [default: my_edgedb_app]:
-> my_edgedb_app
-Checking EdgeDB versions...
-Specify the version of EdgeDB to use with this project [default: x.y]:
+Specify the name of Gel instance to use with this project [default: my_gel_app]:
+> my_gel_app
+Checking Gel versions...
+Specify the version of Gel to use with this project [default: x.y]:
> x.y
-┌─────────────────────┬────────────────────────────────────────────────────────────────────────┐
-│ Project directory │ /Users/colinmcd94/Documents/bun/fun/examples/my-edgedb-app │
-│ Project config │ /Users/colinmcd94/Documents/bun/fun/examples/my-edgedb-app/edgedb.toml │
-│ Schema dir (empty) │ /Users/colinmcd94/Documents/bun/fun/examples/my-edgedb-app/dbschema │
-│ Installation method │ portable package │
-│ Version │ x.y+6d5921b │
-│ Instance name │ my_edgedb_app │
-└─────────────────────┴────────────────────────────────────────────────────────────────────────┘
+┌─────────────────────┬──────────────────────────────────────────────────────────────────┐
+│ Project directory │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app │
+│ Project config │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/gel.toml│
+│ Schema dir (empty) │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema│
+│ Installation method │ portable package │
+│ Version │ x.y+6d5921b │
+│ Instance name │ my_gel_app │
+└─────────────────────┴──────────────────────────────────────────────────────────────────┘
Version x.y+6d5921b is already downloaded
-Initializing EdgeDB instance...
+Initializing Gel instance...
Applying migrations...
Everything is up to date. Revision initial
Project initialized.
-To connect to my_edgedb_app, run `edgedb`
+To connect to my_gel_app, run `gel`
```
---
@@ -70,8 +74,8 @@ To connect to my_edgedb_app, run `edgedb`
To see if the database is running, let's open a REPL and run a simple query.
```sh terminal icon="terminal"
-edgedb
-edgedb> select 1 + 1;
+gel
+gel> select 1 + 1;
```
```txt
@@ -81,12 +85,12 @@ edgedb> select 1 + 1;
Then run `\quit` to exit the REPL.
```sh terminal icon="terminal"
-edgedb> \quit
+gel> \quit
```
---
-With the project initialized, we can define a schema. The `edgedb project init` command already created a `dbschema/default.esdl` file to contain our schema.
+With the project initialized, we can define a schema. The `gel project init` command already created a `dbschema/default.esdl` file to contain our schema.
```txt File Tree icon="folder-tree"
dbschema
@@ -112,15 +116,15 @@ module default {
Then generate and apply an initial migration.
```sh terminal icon="terminal"
-edgedb migration create
+gel migration create
```
```txt
-Created /Users/colinmcd94/Documents/bun/fun/examples/my-edgedb-app/dbschema/migrations/00001.edgeql, id: m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq
+Created /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema/migrations/00001.edgeql, id: m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq
```
```sh terminal icon="terminal"
-edgedb migrate
+gel migrate
```
```txt
@@ -129,11 +133,11 @@ Applied m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq (00001.edgeql)
---
-With our schema applied, let's execute some queries using EdgeDB's JavaScript client library. We'll install the client library and EdgeDB's codegen CLI, and create a `seed.ts`.file.
+With our schema applied, let's execute some queries using Gel's JavaScript client library. We'll install the client library and Gel's codegen CLI, and create a `seed.ts`.file.
```sh terminal icon="terminal"
-bun add edgedb
-bun add -D @edgedb/generate
+bun add gel
+bun add -D @gel/generate
touch seed.ts
```
@@ -144,7 +148,7 @@ Paste the following code into `seed.ts`.
The client auto-connects to the database. We insert a couple movies using the `.execute()` method. We will use EdgeQL's `for` expression to turn this bulk insert into a single optimized query.
```ts seed.ts icon="/icons/typescript.svg"
-import { createClient } from "edgedb";
+import { createClient } from "gel";
const client = createClient();
@@ -184,10 +188,10 @@ Seeding complete.
---
-EdgeDB implements a number of code generation tools for TypeScript. To query our newly seeded database in a typesafe way, we'll use `@edgedb/generate` to code-generate the EdgeQL query builder.
+Gel implements a number of code generation tools for TypeScript. To query our newly seeded database in a typesafe way, we'll use `@gel/generate` to code-generate the EdgeQL query builder.
```sh terminal icon="terminal"
-bunx @edgedb/generate edgeql-js
+bunx @gel/generate edgeql-js
```
```txt
@@ -213,7 +217,7 @@ the query builder directory? The following line will be added:
In `index.ts`, we can import the generated query builder from `./dbschema/edgeql-js` and write a simple select query.
```ts index.ts icon="/icons/typescript.svg"
-import { createClient } from "edgedb";
+import { createClient } from "gel";
import e from "./dbschema/edgeql-js";
const client = createClient();
@@ -254,4 +258,4 @@ bun run index.ts
---
-For complete documentation, refer to the [EdgeDB docs](https://www.edgedb.com/docs).
+For complete documentation, refer to the [Gel docs](https://docs.geldata.com/).
diff --git a/docs/guides/ecosystem/tanstack-start.mdx b/docs/guides/ecosystem/tanstack-start.mdx
index 27d6c01255..d7508b3b81 100644
--- a/docs/guides/ecosystem/tanstack-start.mdx
+++ b/docs/guides/ecosystem/tanstack-start.mdx
@@ -48,107 +48,711 @@ mode: center
## Hosting
-
-
- Add [Nitro](https://nitro.build/) to your project. This tool allows you to deploy your TanStack Start app to different platforms.
+To host your TanStack Start app, you can use [Nitro](https://nitro.build/) or a custom Bun server for production deployments.
- ```sh terminal icon="terminal"
- bun add nitro
- ```
+
+
+
+
+ Add [Nitro](https://nitro.build/) to your project. This tool allows you to deploy your TanStack Start app to different platforms.
-
- Update your vite.config.ts file}>
- Update your `vite.config.ts` file to include the necessary plugins for TanStack Start with Bun.
+ ```sh terminal icon="terminal"
+ bun add nitro
+ ```
- ```ts vite.config.ts icon="/icons/typescript.svg"
- // other imports...
- import { nitro } from "nitro/vite"; // [!code ++]
+
+ Update your vite.config.ts file}>
+ Update your `vite.config.ts` file to include the necessary plugins for TanStack Start with Bun.
- const config = defineConfig({
- plugins: [
- tanstackStart(),
- nitro({ preset: "bun" }), // [!code ++]
- // other plugins...
- ],
- });
+ ```ts vite.config.ts icon="/icons/typescript.svg"
+ // other imports...
+ import { nitro } from "nitro/vite"; // [!code ++]
- export default config;
- ```
+ const config = defineConfig({
+ plugins: [
+ tanstackStart(),
+ nitro({ preset: "bun" }), // [!code ++]
+ // other plugins...
+ ],
+ });
-
- The `bun` preset is optional, but it configures the build output specifically for Bun's runtime.
-
+ export default config;
+ ```
-
-
- Make sure `build` and `start` scripts are present in your `package.json` file:
+
+ The `bun` preset is optional, but it configures the build output specifically for Bun's runtime.
+
- ```json package.json icon="file-json"
- {
- "scripts": {
- "build": "bun --bun vite build", // [!code ++]
- // The .output files are created by Nitro when you run `bun run build`.
- // Not necessary when deploying to Vercel.
- "start": "bun run .output/server/index.mjs" // [!code ++]
- }
- }
- ```
+
+
+ Make sure `build` and `start` scripts are present in your `package.json` file:
+
+ ```json package.json icon="file-json"
+ {
+ "scripts": {
+ "build": "bun --bun vite build", // [!code ++]
+ // The .output files are created by Nitro when you run `bun run build`.
+ // Not necessary when deploying to Vercel.
+ "start": "bun run .output/server/index.mjs" // [!code ++]
+ }
+ }
+ ```
-
- You do **not** need the custom `start` script when deploying to Vercel.
-
+
+ You do **not** need the custom `start` script when deploying to Vercel.
+
-
-
- Check out one of our guides to deploy your app to a hosting provider.
+
+
+ Check out one of our guides to deploy your app to a hosting provider.
-
- When deploying to Vercel, you can either add the `"bunVersion": "1.x"` to your `vercel.json` file, or add it to the `nitro` config in your `vite.config.ts` file:
+
+ When deploying to Vercel, you can either add the `"bunVersion": "1.x"` to your `vercel.json` file, or add it to the `nitro` config in your `vite.config.ts` file:
-
- Do **not** use the `bun` Nitro preset when deploying to Vercel.
-
+
+ Do **not** use the `bun` Nitro preset when deploying to Vercel.
+
- ```ts vite.config.ts icon="/icons/typescript.svg"
- export default defineConfig({
- plugins: [
- tanstackStart(),
- nitro({
- preset: "bun", // [!code --]
- vercel: { // [!code ++]
- functions: { // [!code ++]
- runtime: "bun1.x", // [!code ++]
+ ```ts vite.config.ts icon="/icons/typescript.svg"
+ export default defineConfig({
+ plugins: [
+ tanstackStart(),
+ nitro({
+ preset: "bun", // [!code --]
+ vercel: { // [!code ++]
+ functions: { // [!code ++]
+ runtime: "bun1.x", // [!code ++]
+ }, // [!code ++]
}, // [!code ++]
- }, // [!code ++]
- }),
- ],
- });
- ```
+ }),
+ ],
+ });
+ ```
+
+
+
+
+
+
+
+ This custom server implementation is based on [TanStack's Bun template](https://github.com/TanStack/router/blob/main/examples/react/start-bun/server.ts). It provides fine-grained control over static asset serving, including configurable memory management that preloads small files into memory for fast serving while serving larger files on-demand. This approach is useful when you need precise control over resource usage and asset loading behavior in production deployments.
-
-
- Deploy on Vercel
-
-
- Deploy on Render
-
-
- Deploy on Railway
-
-
- Deploy on DigitalOcean
-
-
- Deploy on AWS Lambda
-
-
- Deploy on Google Cloud Run
-
-
+
+
+ Create a `server.ts` file in your project root with the following custom server implementation:
-
-
+ ```ts server.ts icon="/icons/typescript.svg" expandable
+ /**
+ * TanStack Start Production Server with Bun
+ *
+ * A high-performance production server for TanStack Start applications that
+ * implements intelligent static asset loading with configurable memory management.
+ *
+ * Features:
+ * - Hybrid loading strategy (preload small files, serve large files on-demand)
+ * - Configurable file filtering with include/exclude patterns
+ * - Memory-efficient response generation
+ * - Production-ready caching headers
+ *
+ * Environment Variables:
+ *
+ * PORT (number)
+ * - Server port number
+ * - Default: 3000
+ *
+ * ASSET_PRELOAD_MAX_SIZE (number)
+ * - Maximum file size in bytes to preload into memory
+ * - Files larger than this will be served on-demand from disk
+ * - Default: 5242880 (5MB)
+ * - Example: ASSET_PRELOAD_MAX_SIZE=5242880 (5MB)
+ *
+ * ASSET_PRELOAD_INCLUDE_PATTERNS (string)
+ * - Comma-separated list of glob patterns for files to include
+ * - If specified, only matching files are eligible for preloading
+ * - Patterns are matched against filenames only, not full paths
+ * - Example: ASSET_PRELOAD_INCLUDE_PATTERNS="*.js,*.css,*.woff2"
+ *
+ * ASSET_PRELOAD_EXCLUDE_PATTERNS (string)
+ * - Comma-separated list of glob patterns for files to exclude
+ * - Applied after include patterns
+ * - Patterns are matched against filenames only, not full paths
+ * - Example: ASSET_PRELOAD_EXCLUDE_PATTERNS="*.map,*.txt"
+ *
+ * ASSET_PRELOAD_VERBOSE_LOGGING (boolean)
+ * - Enable detailed logging of loaded and skipped files
+ * - Default: false
+ * - Set to "true" to enable verbose output
+ *
+ * ASSET_PRELOAD_ENABLE_ETAG (boolean)
+ * - Enable ETag generation for preloaded assets
+ * - Default: true
+ * - Set to "false" to disable ETag support
+ *
+ * ASSET_PRELOAD_ENABLE_GZIP (boolean)
+ * - Enable Gzip compression for eligible assets
+ * - Default: true
+ * - Set to "false" to disable Gzip compression
+ *
+ * ASSET_PRELOAD_GZIP_MIN_SIZE (number)
+ * - Minimum file size in bytes required for Gzip compression
+ * - Files smaller than this will not be compressed
+ * - Default: 1024 (1KB)
+ *
+ * ASSET_PRELOAD_GZIP_MIME_TYPES (string)
+ * - Comma-separated list of MIME types eligible for Gzip compression
+ * - Supports partial matching for types ending with "/"
+ * - Default: text/,application/javascript,application/json,application/xml,image/svg+xml
+ *
+ * Usage:
+ * bun run server.ts
+ */
+
+ import path from 'node:path'
+
+ // Configuration
+ const SERVER_PORT = Number(process.env.PORT ?? 3000)
+ const CLIENT_DIRECTORY = './dist/client'
+ const SERVER_ENTRY_POINT = './dist/server/server.js'
+
+ // Logging utilities for professional output
+ const log = {
+ info: (message: string) => {
+ console.log(`[INFO] ${message}`)
+ },
+ success: (message: string) => {
+ console.log(`[SUCCESS] ${message}`)
+ },
+ warning: (message: string) => {
+ console.log(`[WARNING] ${message}`)
+ },
+ error: (message: string) => {
+ console.log(`[ERROR] ${message}`)
+ },
+ header: (message: string) => {
+ console.log(`\n${message}\n`)
+ },
+ }
+
+ // Preloading configuration from environment variables
+ const MAX_PRELOAD_BYTES = Number(
+ process.env.ASSET_PRELOAD_MAX_SIZE ?? 5 * 1024 * 1024, // 5MB default
+ )
+
+ // Parse comma-separated include patterns (no defaults)
+ const INCLUDE_PATTERNS = (process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ .map((pattern: string) => convertGlobToRegExp(pattern))
+
+ // Parse comma-separated exclude patterns (no defaults)
+ const EXCLUDE_PATTERNS = (process.env.ASSET_PRELOAD_EXCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ .map((pattern: string) => convertGlobToRegExp(pattern))
+
+ // Verbose logging flag
+ const VERBOSE = process.env.ASSET_PRELOAD_VERBOSE_LOGGING === 'true'
+
+ // Optional ETag feature
+ const ENABLE_ETAG = (process.env.ASSET_PRELOAD_ENABLE_ETAG ?? 'true') === 'true'
+
+ // Optional Gzip feature
+ const ENABLE_GZIP = (process.env.ASSET_PRELOAD_ENABLE_GZIP ?? 'true') === 'true'
+ const GZIP_MIN_BYTES = Number(process.env.ASSET_PRELOAD_GZIP_MIN_SIZE ?? 1024) // 1KB
+ const GZIP_TYPES = (
+ process.env.ASSET_PRELOAD_GZIP_MIME_TYPES ??
+ 'text/,application/javascript,application/json,application/xml,image/svg+xml'
+ )
+ .split(',')
+ .map((v) => v.trim())
+ .filter(Boolean)
+
+ /**
+ * Convert a simple glob pattern to a regular expression
+ * Supports * wildcard for matching any characters
+ */
+ function convertGlobToRegExp(globPattern: string): RegExp {
+ // Escape regex special chars except *, then replace * with .*
+ const escapedPattern = globPattern
+ .replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&')
+ .replace(/\*/g, '.*')
+ return new RegExp(`^${escapedPattern}$`, 'i')
+ }
+
+ /**
+ * Compute ETag for a given data buffer
+ */
+ function computeEtag(data: Uint8Array): string {
+ const hash = Bun.hash(data)
+ return `W/"${hash.toString(16)}-${data.byteLength.toString()}"`
+ }
+
+ /**
+ * Metadata for preloaded static assets
+ */
+ interface AssetMetadata {
+ route: string
+ size: number
+ type: string
+ }
+
+ /**
+ * In-memory asset with ETag and Gzip support
+ */
+ interface InMemoryAsset {
+ raw: Uint8Array
+ gz?: Uint8Array
+ etag?: string
+ type: string
+ immutable: boolean
+ size: number
+ }
+
+ /**
+ * Result of static asset preloading process
+ */
+ interface PreloadResult {
+ routes: Record Response | Promise>
+ loaded: AssetMetadata[]
+ skipped: AssetMetadata[]
+ }
+
+ /**
+ * Check if a file is eligible for preloading based on configured patterns
+ */
+ function isFileEligibleForPreloading(relativePath: string): boolean {
+ const fileName = relativePath.split(/[/\\]/).pop() ?? relativePath
+
+ // If include patterns are specified, file must match at least one
+ if (INCLUDE_PATTERNS.length > 0) {
+ if (!INCLUDE_PATTERNS.some((pattern) => pattern.test(fileName))) {
+ return false
+ }
+ }
+
+ // If exclude patterns are specified, file must not match any
+ if (EXCLUDE_PATTERNS.some((pattern) => pattern.test(fileName))) {
+ return false
+ }
+
+ return true
+ }
+
+ /**
+ * Check if a MIME type is compressible
+ */
+ function isMimeTypeCompressible(mimeType: string): boolean {
+ return GZIP_TYPES.some((type) =>
+ type.endsWith('/') ? mimeType.startsWith(type) : mimeType === type,
+ )
+ }
+
+ /**
+ * Conditionally compress data based on size and MIME type
+ */
+ function compressDataIfAppropriate(
+ data: Uint8Array,
+ mimeType: string,
+ ): Uint8Array | undefined {
+ if (!ENABLE_GZIP) return undefined
+ if (data.byteLength < GZIP_MIN_BYTES) return undefined
+ if (!isMimeTypeCompressible(mimeType)) return undefined
+ try {
+ return Bun.gzipSync(data.buffer as ArrayBuffer)
+ } catch {
+ return undefined
+ }
+ }
+
+ /**
+ * Create response handler function with ETag and Gzip support
+ */
+ function createResponseHandler(
+ asset: InMemoryAsset,
+ ): (req: Request) => Response {
+ return (req: Request) => {
+ const headers: Record = {
+ 'Content-Type': asset.type,
+ 'Cache-Control': asset.immutable
+ ? 'public, max-age=31536000, immutable'
+ : 'public, max-age=3600',
+ }
+
+ if (ENABLE_ETAG && asset.etag) {
+ const ifNone = req.headers.get('if-none-match')
+ if (ifNone && ifNone === asset.etag) {
+ return new Response(null, {
+ status: 304,
+ headers: { ETag: asset.etag },
+ })
+ }
+ headers.ETag = asset.etag
+ }
+
+ if (
+ ENABLE_GZIP &&
+ asset.gz &&
+ req.headers.get('accept-encoding')?.includes('gzip')
+ ) {
+ headers['Content-Encoding'] = 'gzip'
+ headers['Content-Length'] = String(asset.gz.byteLength)
+ const gzCopy = new Uint8Array(asset.gz)
+ return new Response(gzCopy, { status: 200, headers })
+ }
+
+ headers['Content-Length'] = String(asset.raw.byteLength)
+ const rawCopy = new Uint8Array(asset.raw)
+ return new Response(rawCopy, { status: 200, headers })
+ }
+ }
+
+ /**
+ * Create composite glob pattern from include patterns
+ */
+ function createCompositeGlobPattern(): Bun.Glob {
+ const raw = (process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? '')
+ .split(',')
+ .map((s) => s.trim())
+ .filter(Boolean)
+ if (raw.length === 0) return new Bun.Glob('**/*')
+ if (raw.length === 1) return new Bun.Glob(raw[0])
+ return new Bun.Glob(`{${raw.join(',')}}`)
+ }
+
+ /**
+ * Initialize static routes with intelligent preloading strategy
+ * Small files are loaded into memory, large files are served on-demand
+ */
+ async function initializeStaticRoutes(
+ clientDirectory: string,
+ ): Promise {
+ const routes: Record Response | Promise> =
+ {}
+ const loaded: AssetMetadata[] = []
+ const skipped: AssetMetadata[] = []
+
+ log.info(`Loading static assets from ${clientDirectory}...`)
+ if (VERBOSE) {
+ console.log(
+ `Max preload size: ${(MAX_PRELOAD_BYTES / 1024 / 1024).toFixed(2)} MB`,
+ )
+ if (INCLUDE_PATTERNS.length > 0) {
+ console.log(
+ `Include patterns: ${process.env.ASSET_PRELOAD_INCLUDE_PATTERNS ?? ''}`,
+ )
+ }
+ if (EXCLUDE_PATTERNS.length > 0) {
+ console.log(
+ `Exclude patterns: ${process.env.ASSET_PRELOAD_EXCLUDE_PATTERNS ?? ''}`,
+ )
+ }
+ }
+
+ let totalPreloadedBytes = 0
+
+ try {
+ const glob = createCompositeGlobPattern()
+ for await (const relativePath of glob.scan({ cwd: clientDirectory })) {
+ const filepath = path.join(clientDirectory, relativePath)
+ const route = `/${relativePath.split(path.sep).join(path.posix.sep)}`
+
+ try {
+ // Get file metadata
+ const file = Bun.file(filepath)
+
+ // Skip if file doesn't exist or is empty
+ if (!(await file.exists()) || file.size === 0) {
+ continue
+ }
+
+ const metadata: AssetMetadata = {
+ route,
+ size: file.size,
+ type: file.type || 'application/octet-stream',
+ }
+
+ // Determine if file should be preloaded
+ const matchesPattern = isFileEligibleForPreloading(relativePath)
+ const withinSizeLimit = file.size <= MAX_PRELOAD_BYTES
+
+ if (matchesPattern && withinSizeLimit) {
+ // Preload small files into memory with ETag and Gzip support
+ const bytes = new Uint8Array(await file.arrayBuffer())
+ const gz = compressDataIfAppropriate(bytes, metadata.type)
+ const etag = ENABLE_ETAG ? computeEtag(bytes) : undefined
+ const asset: InMemoryAsset = {
+ raw: bytes,
+ gz,
+ etag,
+ type: metadata.type,
+ immutable: true,
+ size: bytes.byteLength,
+ }
+ routes[route] = createResponseHandler(asset)
+
+ loaded.push({ ...metadata, size: bytes.byteLength })
+ totalPreloadedBytes += bytes.byteLength
+ } else {
+ // Serve large or filtered files on-demand
+ routes[route] = () => {
+ const fileOnDemand = Bun.file(filepath)
+ return new Response(fileOnDemand, {
+ headers: {
+ 'Content-Type': metadata.type,
+ 'Cache-Control': 'public, max-age=3600',
+ },
+ })
+ }
+
+ skipped.push(metadata)
+ }
+ } catch (error: unknown) {
+ if (error instanceof Error && error.name !== 'EISDIR') {
+ log.error(`Failed to load ${filepath}: ${error.message}`)
+ }
+ }
+ }
+
+ // Show detailed file overview only when verbose mode is enabled
+ if (VERBOSE && (loaded.length > 0 || skipped.length > 0)) {
+ const allFiles = [...loaded, ...skipped].sort((a, b) =>
+ a.route.localeCompare(b.route),
+ )
+
+ // Calculate max path length for alignment
+ const maxPathLength = Math.min(
+ Math.max(...allFiles.map((f) => f.route.length)),
+ 60,
+ )
+
+ // Format file size with KB and actual gzip size
+ const formatFileSize = (bytes: number, gzBytes?: number) => {
+ const kb = bytes / 1024
+ const sizeStr = kb < 100 ? kb.toFixed(2) : kb.toFixed(1)
+
+ if (gzBytes !== undefined) {
+ const gzKb = gzBytes / 1024
+ const gzStr = gzKb < 100 ? gzKb.toFixed(2) : gzKb.toFixed(1)
+ return {
+ size: sizeStr,
+ gzip: gzStr,
+ }
+ }
+
+ // Rough gzip estimation (typically 30-70% compression) if no actual gzip data
+ const gzipKb = kb * 0.35
+ return {
+ size: sizeStr,
+ gzip: gzipKb < 100 ? gzipKb.toFixed(2) : gzipKb.toFixed(1),
+ }
+ }
+
+ if (loaded.length > 0) {
+ console.log('\n📁 Preloaded into memory:')
+ console.log(
+ 'Path │ Size │ Gzip Size',
+ )
+ loaded
+ .sort((a, b) => a.route.localeCompare(b.route))
+ .forEach((file) => {
+ const { size, gzip } = formatFileSize(file.size)
+ const paddedPath = file.route.padEnd(maxPathLength)
+ const sizeStr = `${size.padStart(7)} kB`
+ const gzipStr = `${gzip.padStart(7)} kB`
+ console.log(`${paddedPath} │ ${sizeStr} │ ${gzipStr}`)
+ })
+ }
+
+ if (skipped.length > 0) {
+ console.log('\n💾 Served on-demand:')
+ console.log(
+ 'Path │ Size │ Gzip Size',
+ )
+ skipped
+ .sort((a, b) => a.route.localeCompare(b.route))
+ .forEach((file) => {
+ const { size, gzip } = formatFileSize(file.size)
+ const paddedPath = file.route.padEnd(maxPathLength)
+ const sizeStr = `${size.padStart(7)} kB`
+ const gzipStr = `${gzip.padStart(7)} kB`
+ console.log(`${paddedPath} │ ${sizeStr} │ ${gzipStr}`)
+ })
+ }
+ }
+
+ // Show detailed verbose info if enabled
+ if (VERBOSE) {
+ if (loaded.length > 0 || skipped.length > 0) {
+ const allFiles = [...loaded, ...skipped].sort((a, b) =>
+ a.route.localeCompare(b.route),
+ )
+ console.log('\n📊 Detailed file information:')
+ console.log(
+ 'Status │ Path │ MIME Type │ Reason',
+ )
+ allFiles.forEach((file) => {
+ const isPreloaded = loaded.includes(file)
+ const status = isPreloaded ? 'MEMORY' : 'ON-DEMAND'
+ const reason =
+ !isPreloaded && file.size > MAX_PRELOAD_BYTES
+ ? 'too large'
+ : !isPreloaded
+ ? 'filtered'
+ : 'preloaded'
+ const route =
+ file.route.length > 30
+ ? file.route.substring(0, 27) + '...'
+ : file.route
+ console.log(
+ `${status.padEnd(12)} │ ${route.padEnd(30)} │ ${file.type.padEnd(28)} │ ${reason.padEnd(10)}`,
+ )
+ })
+ } else {
+ console.log('\n📊 No files found to display')
+ }
+ }
+
+ // Log summary after the file list
+ console.log() // Empty line for separation
+ if (loaded.length > 0) {
+ log.success(
+ `Preloaded ${String(loaded.length)} files (${(totalPreloadedBytes / 1024 / 1024).toFixed(2)} MB) into memory`,
+ )
+ } else {
+ log.info('No files preloaded into memory')
+ }
+
+ if (skipped.length > 0) {
+ const tooLarge = skipped.filter((f) => f.size > MAX_PRELOAD_BYTES).length
+ const filtered = skipped.length - tooLarge
+ log.info(
+ `${String(skipped.length)} files will be served on-demand (${String(tooLarge)} too large, ${String(filtered)} filtered)`,
+ )
+ }
+ } catch (error) {
+ log.error(
+ `Failed to load static files from ${clientDirectory}: ${String(error)}`,
+ )
+ }
+
+ return { routes, loaded, skipped }
+ }
+
+ /**
+ * Initialize the server
+ */
+ async function initializeServer() {
+ log.header('Starting Production Server')
+
+ // Load TanStack Start server handler
+ let handler: { fetch: (request: Request) => Response | Promise }
+ try {
+ const serverModule = (await import(SERVER_ENTRY_POINT)) as {
+ default: { fetch: (request: Request) => Response | Promise }
+ }
+ handler = serverModule.default
+ log.success('TanStack Start application handler initialized')
+ } catch (error) {
+ log.error(`Failed to load server handler: ${String(error)}`)
+ process.exit(1)
+ }
+
+ // Build static routes with intelligent preloading
+ const { routes } = await initializeStaticRoutes(CLIENT_DIRECTORY)
+
+ // Create Bun server
+ const server = Bun.serve({
+ port: SERVER_PORT,
+
+ routes: {
+ // Serve static assets (preloaded or on-demand)
+ ...routes,
+
+ // Fallback to TanStack Start handler for all other routes
+ '/*': (req: Request) => {
+ try {
+ return handler.fetch(req)
+ } catch (error) {
+ log.error(`Server handler error: ${String(error)}`)
+ return new Response('Internal Server Error', { status: 500 })
+ }
+ },
+ },
+
+ // Global error handler
+ error(error) {
+ log.error(
+ `Uncaught server error: ${error instanceof Error ? error.message : String(error)}`,
+ )
+ return new Response('Internal Server Error', { status: 500 })
+ },
+ })
+
+ log.success(`Server listening on http://localhost:${String(server.port)}`)
+ }
+
+ // Initialize the server
+ initializeServer().catch((error: unknown) => {
+ log.error(`Failed to start server: ${String(error)}`)
+ process.exit(1)
+ })
+ ```
+
+
+
+ Add a `start` script to run the custom server:
+
+ ```json package.json icon="file-json"
+ {
+ "scripts": {
+ "build": "bun --bun vite build",
+ "start": "bun run server.ts" // [!code ++]
+ }
+ }
+ ```
+
+
+
+ Build your application and start the server:
+
+ ```sh terminal icon="terminal"
+ bun run build
+ bun run start
+ ```
+
+ The server will start on port 3000 by default (configurable via `PORT` environment variable).
+
+
+
+
+
+
+
+
+
+ Deploy on Vercel
+
+
+ Deploy on Render
+
+
+ Deploy on Railway
+
+
+ Deploy on DigitalOcean
+
+
+ Deploy on AWS Lambda
+
+
+ Deploy on Google Cloud Run
+
+
+
+---
[→ See TanStack Start's official documentation](https://tanstack.com/start/latest/docs/framework/react/guide/hosting) for more information on hosting.
diff --git a/docs/guides/read-file/watch.mdx b/docs/guides/read-file/watch.mdx
index ab27043c88..dde7a8c2a1 100644
--- a/docs/guides/read-file/watch.mdx
+++ b/docs/guides/read-file/watch.mdx
@@ -23,8 +23,8 @@ To listen to changes in subdirectories, pass the `recursive: true` option to `fs
```ts
import { watch } from "fs";
-const watcher = watch(import.meta.dir, { recursive: true }, (event, filename) => {
- console.log(`Detected ${event} in ${filename}`);
+const watcher = watch(import.meta.dir, { recursive: true }, (event, relativePath) => {
+ console.log(`Detected ${event} in ${relativePath}`);
});
```
diff --git a/docs/quickstart.mdx b/docs/quickstart.mdx
index 78948faed9..21509db9f7 100644
--- a/docs/quickstart.mdx
+++ b/docs/quickstart.mdx
@@ -12,198 +12,204 @@ Build a minimal HTTP server with `Bun.serve`, run it locally, then evolve it by
---
-
- Initialize a new project with `bun init`.
+
- ```bash terminal icon="terminal"
- bun init my-app
- ```
+ Initialize a new project with `bun init`.
- It'll prompt you to pick a template, either `Blank`, `React`, or `Library`. For this guide, we'll pick `Blank`.
+ ```bash terminal icon="terminal"
+ bun init my-app
+ ```
- ```bash terminal icon="terminal"
- bun init my-app
- ```
- ```txt
- ✓ Select a project template: Blank
+ It'll prompt you to pick a template, either `Blank`, `React`, or `Library`. For this guide, we'll pick `Blank`.
-- .gitignore
-- CLAUDE.md
-- .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc -> CLAUDE.md
-- index.ts
-- tsconfig.json (for editor autocomplete)
-- README.md
+ ```bash terminal icon="terminal"
+ bun init my-app
+ ```
+ ```txt
+ ✓ Select a project template: Blank
- ````
+ - .gitignore
+ - CLAUDE.md
+ - .cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc -> CLAUDE.md
+ - index.ts
+ - tsconfig.json (for editor autocomplete)
+ - README.md
+ ```
- This automatically creates a `my-app` directory with a basic Bun app.
-
-
+ This automatically creates a `my-app` directory with a basic Bun app.
- Run the `index.ts` file using `bun run index.ts`.
+
+
- ```bash terminal icon="terminal"
- cd my-app
- bun run index.ts
- ```
- ```txt
- Hello via Bun!
- ```
+ Run the `index.ts` file using `bun run index.ts`.
- You should see a console output saying `"Hello via Bun!"`.
-
-
- Replace the contents of `index.ts` with the following code:
+ ```bash terminal icon="terminal"
+ cd my-app
+ bun run index.ts
+ ```
+ ```txt
+ Hello via Bun!
+ ```
- ```ts index.ts icon="/icons/typescript.svg"
- const server = Bun.serve({
- port: 3000,
- routes: {
- "/": () => new Response('Bun!'),
- }
- });
+ You should see a console output saying `"Hello via Bun!"`.
- console.log(`Listening on ${server.url}`);
- ```
+
+
- Run the `index.ts` file again using `bun run index.ts`.
+ Replace the contents of `index.ts` with the following code:
- ```bash terminal icon="terminal"
- bun run index.ts
- ```
- ```txt
- Listening on http://localhost:3000
- ```
+ ```ts index.ts icon="/icons/typescript.svg"
+ const server = Bun.serve({
+ port: 3000,
+ routes: {
+ "/": () => new Response('Bun!'),
+ }
+ });
- Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see a simple page that says `"Bun!"`.
+ console.log(`Listening on ${server.url}`);
+ ```
+ Run the `index.ts` file again using `bun run index.ts`.
-
- If you used `bun init`, Bun will have automatically installed Bun's TypeScript declarations and configured your `tsconfig.json`. If you're trying out Bun in an existing project, you may see a type error on the `Bun` global.
+ ```bash terminal icon="terminal"
+ bun run index.ts
+ ```
+ ```txt
+ Listening on http://localhost:3000
+ ```
- To fix this, first install `@types/bun` as a dev dependency.
+ Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see a simple page that says `"Bun!"`.
- ```bash terminal icon="terminal"
- bun add -d @types/bun
- ```
+
- Then add the following to your `compilerOptions` in `tsconfig.json`:
+ If you used `bun init`, Bun will have automatically installed Bun's TypeScript declarations and configured your `tsconfig.json`. If you're trying out Bun in an existing project, you may see a type error on the `Bun` global.
- ```json tsconfig.json icon="file-code"
- {
- "compilerOptions": {
- "lib": ["ESNext"],
- "target": "ESNext",
- "module": "Preserve",
- "moduleDetection": "force",
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "verbatimModuleSyntax": true,
- "noEmit": true
- }
- }
- ```
+ To fix this, first install `@types/bun` as a dev dependency.
-
+ ```bash terminal icon="terminal"
+ bun add -d @types/bun
+ ```
-
-
- Install the `figlet` package and its type declarations. Figlet is a utility for converting strings into ASCII art.
+ Then add the following to your `compilerOptions` in `tsconfig.json`:
- ```bash terminal icon="terminal"
- bun add figlet
- bun add -d @types/figlet # TypeScript users only
- ```
+ ```json tsconfig.json icon="file-code"
+ {
+ "compilerOptions": {
+ "lib": ["ESNext"],
+ "target": "ESNext",
+ "module": "Preserve",
+ "moduleDetection": "force",
+ "moduleResolution": "bundler",
+ "allowImportingTsExtensions": true,
+ "verbatimModuleSyntax": true,
+ "noEmit": true
+ }
+ }
+ ```
- Update `index.ts` to use `figlet` in `routes`.
+
- ```ts index.ts icon="/icons/typescript.svg"
- import figlet from 'figlet'; // [!code ++]
+
+
- const server = Bun.serve({
- port: 3000,
- routes: {
- "/": () => new Response('Bun!'),
- "/figlet": () => { // [!code ++]
- const body = figlet.textSync('Bun!'); // [!code ++]
- return new Response(body); // [!code ++]
- } // [!code ++]
- }
- });
+ Install the `figlet` package and its type declarations. Figlet is a utility for converting strings into ASCII art.
- console.log(`Listening on ${server.url}`);
- ```
+ ```bash terminal icon="terminal"
+ bun add figlet
+ bun add -d @types/figlet # TypeScript users only
+ ```
- Run the `index.ts` file again using `bun run index.ts`.
+ Update `index.ts` to use `figlet` in `routes`.
- ```bash terminal icon="terminal"
- bun run index.ts
- ```
- ```txt
- Listening on http://localhost:3000
- ```
+ ```ts index.ts icon="/icons/typescript.svg"
+ import figlet from 'figlet'; // [!code ++]
- Visit [`http://localhost:3000/figlet`](http://localhost:3000/figlet) to test the server. You should see a simple page that says `"Bun!"` in ASCII art.
+ const server = Bun.serve({
+ port: 3000,
+ routes: {
+ "/": () => new Response('Bun!'),
+ "/figlet": () => { // [!code ++]
+ const body = figlet.textSync('Bun!'); // [!code ++]
+ return new Response(body); // [!code ++]
+ } // [!code ++]
+ }
+ });
- ```txt
- ____ _
- | __ ) _ _ _ __ | |
- | _ \| | | | '_ \| |
- | |_) | |_| | | | |_|
- |____/ \__,_|_| |_(_)
- ```
-
-
- Let's add some HTML. Create a new file called `index.html` and add the following code:
+ console.log(`Listening on ${server.url}`);
+ ```
- ```html index.html icon="file-code"
-
-
-
-
-
- Bun
-
-
-
Bun!
-
-
- ```
+ Run the `index.ts` file again using `bun run index.ts`.
- Then, import this file in `index.ts` and serve it from the root `/` route.
+ ```bash terminal icon="terminal"
+ bun run index.ts
+ ```
+ ```txt
+ Listening on http://localhost:3000
+ ```
- ```ts index.ts icon="/icons/typescript.svg"
- import figlet from 'figlet';
- import index from './index.html'; // [!code ++]
+ Visit [`http://localhost:3000/figlet`](http://localhost:3000/figlet) to test the server. You should see a simple page that says `"Bun!"` in ASCII art.
- const server = Bun.serve({
- port: 3000,
- routes: {
- "/": index, // [!code ++]
- "/figlet": () => {
- const body = figlet.textSync('Bun!');
- return new Response(body);
- }
- }
- });
+ ```txt
+ ____ _
+ | __ ) _ _ _ __ | |
+ | _ \| | | | '_ \| |
+ | |_) | |_| | | | |_|
+ |____/ \__,_|_| |_(_)
+ ```
- console.log(`Listening on ${server.url}`);
- ```
+
+
- Run the `index.ts` file again using `bun run index.ts`.
+ Let's add some HTML. Create a new file called `index.html` and add the following code:
- ```bash terminal icon="terminal"
- bun run index.ts
- ```
- ```txt
- Listening on http://localhost:3000
- ```
+ ```html index.html icon="file-code"
+
+
+
+
+
+ Bun
+
+
+
Bun!
+
+
+ ```
- Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see the static HTML page.
-
+ Then, import this file in `index.ts` and serve it from the root `/` route.
-
- ````
+ ```ts index.ts icon="/icons/typescript.svg"
+ import figlet from 'figlet';
+ import index from './index.html'; // [!code ++]
+
+ const server = Bun.serve({
+ port: 3000,
+ routes: {
+ "/": index, // [!code ++]
+ "/figlet": () => {
+ const body = figlet.textSync('Bun!');
+ return new Response(body);
+ }
+ }
+ });
+
+ console.log(`Listening on ${server.url}`);
+ ```
+
+ Run the `index.ts` file again using `bun run index.ts`.
+
+ ```bash terminal icon="terminal"
+ bun run index.ts
+ ```
+ ```txt
+ Listening on http://localhost:3000
+ ```
+
+ Visit [`http://localhost:3000`](http://localhost:3000) to test the server. You should see the static HTML page.
+
+
+
+
🎉 Congratulations! You've built a simple HTTP server with Bun and installed a package.
@@ -234,7 +240,7 @@ bun run start
```
```txt
- Listening on http://localhost:3000
+Listening on http://localhost:3000
```
⚡️ **Performance** — `bun run` is roughly 28x faster than `npm run` (6ms vs 170ms of overhead).
diff --git a/docs/runtime/file-types.mdx b/docs/runtime/file-types.mdx
index 87e8284a85..89e23779c1 100644
--- a/docs/runtime/file-types.mdx
+++ b/docs/runtime/file-types.mdx
@@ -5,14 +5,16 @@ description: "File types and loaders supported by Bun's bundler and runtime"
The Bun bundler implements a set of default loaders out of the box. As a rule of thumb, the bundler and the runtime both support the same set of file types out of the box.
-`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.toml` `.json` `.txt` `.wasm` `.node` `.html`
+`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.css` `.json` `.jsonc` `.toml` `.yaml` `.yml` `.txt` `.wasm` `.node` `.html` `.sh`
Bun uses the file extension to determine which built-in _loader_ should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](/bundler/plugins) that extend Bun with custom loaders.
-You can explicitly specify which loader to use using the 'loader' import attribute.
+You can explicitly specify which loader to use using the `'type'` import attribute.
```ts
-import my_toml from "./my_file" with { loader: "toml" };
+import my_toml from "./my_file" with { type: "toml" };
+// or with dynamic imports
+const { default: my_toml } = await import("./my_file", { with: { type: "toml" } });
```
---
@@ -84,6 +86,29 @@ export default {
+### `jsonc`
+
+**JSON with Comments loader**. Default for `.jsonc`.
+
+JSONC (JSON with Comments) files can be directly imported. Bun will parse them, stripping out comments and trailing commas.
+
+```ts
+import config from "./config.jsonc";
+console.log(config);
+```
+
+During bundling, the parsed JSONC is inlined into the bundle as a JavaScript object, identical to the `json` loader.
+
+```ts
+var config = {
+ option: "value",
+};
+```
+
+
+ Bun automatically uses the `jsonc` loader for `tsconfig.json`, `jsconfig.json`, `package.json`, and `bun.lock` files.
+
+
### `toml`
**TOML loader**. Default for `.toml`.
@@ -128,6 +153,50 @@ export default {
+### `yaml`
+
+**YAML loader**. Default for `.yaml` and `.yml`.
+
+YAML files can be directly imported. Bun will parse them with its fast native YAML parser.
+
+```ts
+import config from "./config.yaml";
+console.log(config);
+
+// via import attribute:
+import data from "./data.txt" with { type: "yaml" };
+```
+
+During bundling, the parsed YAML is inlined into the bundle as a JavaScript object.
+
+```ts
+var config = {
+ name: "my-app",
+ version: "1.0.0",
+ // ...other fields
+};
+```
+
+If a `.yaml` or `.yml` file is passed as an entrypoint, it will be converted to a `.js` module that `export default`s the parsed object.
+
+
+
+```yaml Input
+name: John Doe
+age: 35
+email: johndoe@example.com
+```
+
+```ts Output
+export default {
+ name: "John Doe",
+ age: 35,
+ email: "johndoe@example.com",
+};
+```
+
+
+
### `text`
**Text loader**. Default for `.txt`.
@@ -283,6 +352,18 @@ The `html` loader behaves differently depending on how it's used:
+### `css`
+
+**CSS loader**. Default for `.css`.
+
+CSS files can be directly imported. This is primarily useful for [full-stack applications](/bundler/html-static) where CSS is bundled alongside HTML.
+
+```ts
+import "./styles.css";
+```
+
+There isn't any value returned from the import, it's only used for side effects.
+
### `sh` loader
**Bun Shell loader**. Default for `.sh` files
diff --git a/docs/snippets/guides.jsx b/docs/snippets/guides.jsx
index ce3c7a7f8a..b17af36b57 100644
--- a/docs/snippets/guides.jsx
+++ b/docs/snippets/guides.jsx
@@ -5,6 +5,12 @@ export const GuidesList = () => {
blurb: "A collection of code samples and walkthroughs for performing common tasks with Bun.",
},
featured: [
+ {
+ category: "Ecosystem",
+ title: "Use Tanstack Start with Bun",
+ href: "/guides/ecosystem/tanstack-start",
+ cta: "View guide",
+ },
{
category: "Ecosystem",
title: "Build a frontend using Vite and Bun",
@@ -35,12 +41,6 @@ export const GuidesList = () => {
href: "/guides/websocket/simple",
cta: "View guide",
},
- {
- category: "Reading files",
- title: "Read a file as a string",
- href: "/guides/read-file/string",
- cta: "View guide",
- },
],
categories: [
{
@@ -123,7 +123,7 @@ export const GuidesList = () => {
title: "Ecosystem",
icon: "puzzle",
items: [
- { title: "Use EdgeDB with Bun", href: "/guides/ecosystem/edgedb" },
+ { title: "Use Gel with Bun", href: "/guides/ecosystem/gel" },
{ title: "Use Prisma ORM with Bun", href: "/guides/ecosystem/prisma" },
{ title: "Use Prisma Postgres with Bun", href: "/guides/ecosystem/prisma-postgres" },
{ title: "Create a Discord bot", href: "/guides/ecosystem/discordjs" },
@@ -135,6 +135,7 @@ export const GuidesList = () => {
{ title: "Build an app with Qwik and Bun", href: "/guides/ecosystem/qwik" },
{ title: "Build an app with Astro and Bun", href: "/guides/ecosystem/astro" },
{ title: "Build an app with Remix and Bun", href: "/guides/ecosystem/remix" },
+ { title: "Use TanStack Start with Bun", href: "/guides/ecosystem/tanstack-start" },
{ title: "Run Bun as a daemon with systemd", href: "/guides/ecosystem/systemd" },
{ title: "Build an app with Next.js and Bun", href: "/guides/ecosystem/nextjs" },
{ title: "Build an app with SvelteKit and Bun", href: "/guides/ecosystem/sveltekit" },
diff --git a/packages/bun-usockets/certdata.txt b/packages/bun-usockets/certdata.txt
index aeedd56c53..17f3489c5e 100644
--- a/packages/bun-usockets/certdata.txt
+++ b/packages/bun-usockets/certdata.txt
@@ -3195,7 +3195,6 @@ CKA_NSS_SERVER_DISTRUST_AFTER MULTILINE_OCTAL
END
CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
-
# Trust for "ePKI Root Certification Authority"
# Issuer: OU=ePKI Root Certification Authority,O="Chunghwa Telecom Co., Ltd.",C=TW
# Serial Number:15:c8:bd:65:47:5c:af:b8:97:00:5e:e4:06:d2:bc:9d
@@ -5240,175 +5239,6 @@ CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-#
-# Certificate "Explicitly Distrust DigiNotar Root CA"
-#
-# Issuer: E=info@diginotar.nl,CN=DigiNotar Root CA,O=DigiNotar,C=NL
-# Serial Number:0f:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff
-# Subject: E=info@diginotar.nl,CN=DigiNotar Root CA,O=DigiNotar,C=NL
-# Not Valid Before: Fri Jul 27 17:19:37 2007
-# Not Valid After : Mon Mar 31 18:19:22 2025
-# Fingerprint (MD5): 0A:A4:D5:CC:BA:B4:FB:A3:59:E3:E6:01:DD:53:D9:4E
-# Fingerprint (SHA1): C1:77:CB:4B:E0:B4:26:8E:F5:C7:CF:45:99:22:B9:B0:CE:BA:21:2F
-CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Root CA"
-CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
-CKA_SUBJECT MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_ID UTF8 "0"
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\017\377\377\377\377\377\377\377\377\377\377\377\377\377
-\377\377
-END
-CKA_VALUE MULTILINE_OCTAL
-\060\202\005\212\060\202\003\162\240\003\002\001\002\002\020\017
-\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\060
-\015\006\011\052\206\110\206\367\015\001\001\005\005\000\060\137
-\061\013\060\011\006\003\125\004\006\023\002\116\114\061\022\060
-\020\006\003\125\004\012\023\011\104\151\147\151\116\157\164\141
-\162\061\032\060\030\006\003\125\004\003\023\021\104\151\147\151
-\116\157\164\141\162\040\122\157\157\164\040\103\101\061\040\060
-\036\006\011\052\206\110\206\367\015\001\011\001\026\021\151\156
-\146\157\100\144\151\147\151\156\157\164\141\162\056\156\154\060
-\036\027\015\060\067\060\067\062\067\061\067\061\071\063\067\132
-\027\015\062\065\060\063\063\061\061\070\061\071\062\062\132\060
-\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061\022
-\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157\164
-\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151\147
-\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061\040
-\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021\151
-\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156\154
-\060\202\002\042\060\015\006\011\052\206\110\206\367\015\001\001
-\001\005\000\003\202\002\017\000\060\202\002\012\002\202\002\001
-\000\254\260\130\301\000\275\330\041\010\013\053\232\376\156\126
-\060\005\237\033\167\220\020\101\134\303\015\207\021\167\216\201
-\361\312\174\351\214\152\355\070\164\065\273\332\337\371\273\300
-\011\067\264\226\163\201\175\063\032\230\071\367\223\157\225\177
-\075\271\261\165\207\272\121\110\350\213\160\076\225\004\305\330
-\266\303\026\331\210\260\261\207\035\160\332\206\264\017\024\213
-\172\317\020\321\164\066\242\022\173\167\206\112\171\346\173\337
-\002\021\150\245\116\206\256\064\130\233\044\023\170\126\042\045
-\036\001\213\113\121\161\373\202\314\131\226\151\210\132\150\123
-\305\271\015\002\067\313\113\274\146\112\220\176\052\013\005\007
-\355\026\137\125\220\165\330\106\311\033\203\342\010\276\361\043
-\314\231\035\326\052\017\203\040\025\130\047\202\056\372\342\042
-\302\111\261\271\001\201\152\235\155\235\100\167\150\166\116\041
-\052\155\204\100\205\116\166\231\174\202\363\363\267\002\131\324
-\046\001\033\216\337\255\123\006\321\256\030\335\342\262\072\313
-\327\210\070\216\254\133\051\271\031\323\230\371\030\003\317\110
-\202\206\146\013\033\151\017\311\353\070\210\172\046\032\005\114
-\222\327\044\324\226\362\254\122\055\243\107\325\122\366\077\376
-\316\204\006\160\246\252\076\242\362\266\126\064\030\127\242\344
-\201\155\347\312\360\152\323\307\221\153\002\203\101\174\025\357
-\153\232\144\136\343\320\074\345\261\353\173\135\206\373\313\346
-\167\111\315\243\145\334\367\271\234\270\344\013\137\223\317\314
-\060\032\062\034\316\034\143\225\245\371\352\341\164\213\236\351
-\053\251\060\173\240\030\037\016\030\013\345\133\251\323\321\154
-\036\007\147\217\221\113\251\212\274\322\146\252\223\001\210\262
-\221\372\061\134\325\246\301\122\010\011\315\012\143\242\323\042
-\246\350\241\331\071\006\227\365\156\215\002\220\214\024\173\077
-\200\315\033\234\272\304\130\162\043\257\266\126\237\306\172\102
-\063\051\007\077\202\311\346\037\005\015\315\114\050\066\213\323
-\310\076\034\306\210\357\136\356\211\144\351\035\353\332\211\176
-\062\246\151\321\335\314\210\237\321\320\311\146\041\334\006\147
-\305\224\172\232\155\142\114\175\314\340\144\200\262\236\107\216
-\243\002\003\001\000\001\243\102\060\100\060\017\006\003\125\035
-\023\001\001\377\004\005\060\003\001\001\377\060\016\006\003\125
-\035\017\001\001\377\004\004\003\002\001\006\060\035\006\003\125
-\035\016\004\026\004\024\210\150\277\340\216\065\304\073\070\153
-\142\367\050\073\204\201\310\014\327\115\060\015\006\011\052\206
-\110\206\367\015\001\001\005\005\000\003\202\002\001\000\073\002
-\215\313\074\060\350\156\240\255\362\163\263\137\236\045\023\004
-\005\323\366\343\213\273\013\171\316\123\336\344\226\305\321\257
-\163\274\325\303\320\100\125\174\100\177\315\033\137\011\325\362
-\174\237\150\035\273\135\316\172\071\302\214\326\230\173\305\203
-\125\250\325\175\100\312\340\036\367\211\136\143\135\241\023\302
-\135\212\266\212\174\000\363\043\303\355\205\137\161\166\360\150
-\143\252\105\041\071\110\141\170\066\334\361\103\223\324\045\307
-\362\200\145\341\123\002\165\121\374\172\072\357\067\253\204\050
-\127\014\330\324\324\231\126\154\343\242\376\131\204\264\061\350
-\063\370\144\224\224\121\227\253\071\305\113\355\332\335\200\013
-\157\174\051\015\304\216\212\162\015\347\123\024\262\140\101\075
-\204\221\061\150\075\047\104\333\345\336\364\372\143\105\310\114
-\076\230\365\077\101\272\116\313\067\015\272\146\230\361\335\313
-\237\134\367\124\066\202\153\054\274\023\141\227\102\370\170\273
-\314\310\242\237\312\360\150\275\153\035\262\337\215\157\007\235
-\332\216\147\307\107\036\312\271\277\052\102\221\267\143\123\146
-\361\102\243\341\364\132\115\130\153\265\344\244\063\255\134\160
-\035\334\340\362\353\163\024\221\232\003\301\352\000\145\274\007
-\374\317\022\021\042\054\256\240\275\072\340\242\052\330\131\351
-\051\323\030\065\244\254\021\137\031\265\265\033\377\042\112\134
-\306\172\344\027\357\040\251\247\364\077\255\212\247\232\004\045
-\235\016\312\067\346\120\375\214\102\051\004\232\354\271\317\113
-\162\275\342\010\066\257\043\057\142\345\312\001\323\160\333\174
-\202\043\054\026\061\014\306\066\007\220\172\261\037\147\130\304
-\073\130\131\211\260\214\214\120\263\330\206\313\150\243\304\012
-\347\151\113\040\316\301\036\126\113\225\251\043\150\330\060\330
-\303\353\260\125\121\315\345\375\053\270\365\273\021\237\123\124
-\366\064\031\214\171\011\066\312\141\027\045\027\013\202\230\163
-\014\167\164\303\325\015\307\250\022\114\307\247\124\161\107\056
-\054\032\175\311\343\053\073\110\336\047\204\247\143\066\263\175
-\217\240\144\071\044\015\075\173\207\257\146\134\164\033\113\163
-\262\345\214\360\206\231\270\345\305\337\204\301\267\353
-END
-
-# Trust for Certificate "Explicitly Distrust DigiNotar Root CA"
-# Issuer: E=info@diginotar.nl,CN=DigiNotar Root CA,O=DigiNotar,C=NL
-# Serial Number:0f:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff:ff
-# Subject: E=info@diginotar.nl,CN=DigiNotar Root CA,O=DigiNotar,C=NL
-# Not Valid Before: Fri Jul 27 17:19:37 2007
-# Not Valid After : Mon Mar 31 18:19:22 2025
-# Fingerprint (MD5): 0A:A4:D5:CC:BA:B4:FB:A3:59:E3:E6:01:DD:53:D9:4E
-# Fingerprint (SHA1): C1:77:CB:4B:E0:B4:26:8E:F5:C7:CF:45:99:22:B9:B0:CE:BA:21:2F
-CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
-CKA_TOKEN CK_BBOOL CK_TRUE
-CKA_PRIVATE CK_BBOOL CK_FALSE
-CKA_MODIFIABLE CK_BBOOL CK_FALSE
-CKA_LABEL UTF8 "Explicitly Distrust DigiNotar Root CA"
-CKA_CERT_SHA1_HASH MULTILINE_OCTAL
-\301\167\313\113\340\264\046\216\365\307\317\105\231\042\271\260
-\316\272\041\057
-END
-CKA_CERT_MD5_HASH MULTILINE_OCTAL
-\012\244\325\314\272\264\373\243\131\343\346\001\335\123\331\116
-END
-CKA_ISSUER MULTILINE_OCTAL
-\060\137\061\013\060\011\006\003\125\004\006\023\002\116\114\061
-\022\060\020\006\003\125\004\012\023\011\104\151\147\151\116\157
-\164\141\162\061\032\060\030\006\003\125\004\003\023\021\104\151
-\147\151\116\157\164\141\162\040\122\157\157\164\040\103\101\061
-\040\060\036\006\011\052\206\110\206\367\015\001\011\001\026\021
-\151\156\146\157\100\144\151\147\151\156\157\164\141\162\056\156
-\154
-END
-CKA_SERIAL_NUMBER MULTILINE_OCTAL
-\002\020\017\377\377\377\377\377\377\377\377\377\377\377\377\377
-\377\377
-END
-CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_NOT_TRUSTED
-CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
-
#
# Certificate "Security Communication RootCA2"
#
@@ -26918,3 +26748,561 @@ CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "OISTE Client Root ECC G1"
+#
+# Issuer: CN=OISTE Client Root ECC G1,O=OISTE Foundation,C=CH
+# Serial Number:54:ec:97:d6:8b:b4:c4:0b:21:6e:0e:b2:d0:53:c8:7a
+# Subject: CN=OISTE Client Root ECC G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:31:40 2023
+# Not Valid After : Sun May 24 14:31:39 2048
+# Fingerprint (SHA-256): D9:A3:24:85:A8:CC:A8:55:39:CE:F1:2F:FF:FF:71:13:78:A1:78:51:D7:3D:A2:73:2A:B4:30:2D:76:3B:D6:2B
+# Fingerprint (SHA1): C0:2B:13:F9:1D:77:56:ED:6C:92:83:F1:86:DF:2A:D5:1E:6E:F2:BC
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Client Root ECC G1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\124\354\227\326\213\264\304\013\041\156\016\262\320\123
+\310\172
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\064\060\202\001\272\240\003\002\001\002\002\020\124
+\354\227\326\213\264\304\013\041\156\016\262\320\123\310\172\060
+\012\006\010\052\206\110\316\075\004\003\003\060\113\061\013\060
+\011\006\003\125\004\006\023\002\103\110\061\031\060\027\006\003
+\125\004\012\014\020\117\111\123\124\105\040\106\157\165\156\144
+\141\164\151\157\156\061\041\060\037\006\003\125\004\003\014\030
+\117\111\123\124\105\040\103\154\151\145\156\164\040\122\157\157
+\164\040\105\103\103\040\107\061\060\036\027\015\062\063\060\065
+\063\061\061\064\063\061\064\060\132\027\015\064\070\060\065\062
+\064\061\064\063\061\063\071\132\060\113\061\013\060\011\006\003
+\125\004\006\023\002\103\110\061\031\060\027\006\003\125\004\012
+\014\020\117\111\123\124\105\040\106\157\165\156\144\141\164\151
+\157\156\061\041\060\037\006\003\125\004\003\014\030\117\111\123
+\124\105\040\103\154\151\145\156\164\040\122\157\157\164\040\105
+\103\103\040\107\061\060\166\060\020\006\007\052\206\110\316\075
+\002\001\006\005\053\201\004\000\042\003\142\000\004\210\116\150
+\037\311\236\276\072\004\133\025\303\065\364\314\120\305\010\255
+\070\156\250\074\322\002\272\314\253\045\375\165\100\375\147\031
+\237\033\012\135\366\313\026\173\371\134\036\202\334\025\104\324
+\234\074\155\141\223\105\364\117\317\142\271\337\076\123\215\232
+\324\112\336\210\252\013\246\361\324\141\326\036\164\325\030\262
+\305\115\114\357\200\173\354\015\353\203\071\124\226\243\143\060
+\141\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
+\001\377\060\037\006\003\125\035\043\004\030\060\026\200\024\231
+\127\073\071\261\055\000\214\041\146\214\225\151\234\155\165\354
+\214\077\372\060\035\006\003\125\035\016\004\026\004\024\231\127
+\073\071\261\055\000\214\041\146\214\225\151\234\155\165\354\214
+\077\372\060\016\006\003\125\035\017\001\001\377\004\004\003\002
+\001\206\060\012\006\010\052\206\110\316\075\004\003\003\003\150
+\000\060\145\002\061\000\226\377\344\202\116\026\042\133\240\205
+\030\074\075\072\217\040\006\010\045\347\365\221\066\031\255\173
+\264\337\133\146\022\067\163\160\355\315\005\050\007\136\010\316
+\015\102\137\031\221\002\002\060\147\111\207\256\006\101\035\040
+\323\061\246\252\046\067\361\047\212\141\015\376\232\006\103\247
+\056\236\046\107\243\062\030\213\350\136\120\005\361\260\172\110
+\166\336\333\241\142\112\272\167
+END
+CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
+CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
+CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
+
+# Trust for "OISTE Client Root ECC G1"
+# Issuer: CN=OISTE Client Root ECC G1,O=OISTE Foundation,C=CH
+# Serial Number:54:ec:97:d6:8b:b4:c4:0b:21:6e:0e:b2:d0:53:c8:7a
+# Subject: CN=OISTE Client Root ECC G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:31:40 2023
+# Not Valid After : Sun May 24 14:31:39 2048
+# Fingerprint (SHA-256): D9:A3:24:85:A8:CC:A8:55:39:CE:F1:2F:FF:FF:71:13:78:A1:78:51:D7:3D:A2:73:2A:B4:30:2D:76:3B:D6:2B
+# Fingerprint (SHA1): C0:2B:13:F9:1D:77:56:ED:6C:92:83:F1:86:DF:2A:D5:1E:6E:F2:BC
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Client Root ECC G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\300\053\023\371\035\167\126\355\154\222\203\361\206\337\052\325
+\036\156\362\274
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\121\257\341\070\170\021\354\345\310\237\135\233\065\362\114\054
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\124\354\227\326\213\264\304\013\041\156\016\262\320\123
+\310\172
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "OISTE Client Root RSA G1"
+#
+# Issuer: CN=OISTE Client Root RSA G1,O=OISTE Foundation,C=CH
+# Serial Number:34:17:6f:59:01:88:1b:aa:a5:dd:c8:48:bb:b4:3b:73
+# Subject: CN=OISTE Client Root RSA G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:23:29 2023
+# Not Valid After : Sun May 24 14:23:28 2048
+# Fingerprint (SHA-256): D0:2A:0F:99:4A:86:8C:66:39:5F:2E:7A:88:0D:F5:09:BD:0C:29:C9:6D:E1:60:15:A0:FD:50:1E:DA:4F:96:A9
+# Fingerprint (SHA1): BD:A8:13:20:E0:BF:97:ED:A2:8E:9E:18:5F:F2:D5:FE:E5:2B:13:D5
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Client Root RSA G1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\064\027\157\131\001\210\033\252\245\335\310\110\273\264
+\073\163
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\203\060\202\003\153\240\003\002\001\002\002\020\064
+\027\157\131\001\210\033\252\245\335\310\110\273\264\073\163\060
+\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\113
+\061\013\060\011\006\003\125\004\006\023\002\103\110\061\031\060
+\027\006\003\125\004\012\014\020\117\111\123\124\105\040\106\157
+\165\156\144\141\164\151\157\156\061\041\060\037\006\003\125\004
+\003\014\030\117\111\123\124\105\040\103\154\151\145\156\164\040
+\122\157\157\164\040\122\123\101\040\107\061\060\036\027\015\062
+\063\060\065\063\061\061\064\062\063\062\071\132\027\015\064\070
+\060\065\062\064\061\064\062\063\062\070\132\060\113\061\013\060
+\011\006\003\125\004\006\023\002\103\110\061\031\060\027\006\003
+\125\004\012\014\020\117\111\123\124\105\040\106\157\165\156\144
+\141\164\151\157\156\061\041\060\037\006\003\125\004\003\014\030
+\117\111\123\124\105\040\103\154\151\145\156\164\040\122\157\157
+\164\040\122\123\101\040\107\061\060\202\002\042\060\015\006\011
+\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
+\060\202\002\012\002\202\002\001\000\272\117\376\376\124\023\265
+\204\074\274\340\323\061\361\035\156\334\304\123\161\372\344\071
+\121\103\166\175\222\037\201\177\000\153\101\302\346\332\334\030
+\115\154\027\131\160\011\063\142\354\151\210\055\260\335\131\371
+\141\140\140\126\361\266\264\357\353\207\320\023\376\303\317\157
+\217\176\071\130\121\263\211\002\216\124\225\036\042\137\253\050
+\005\103\047\370\105\364\011\102\046\224\376\275\023\170\273\221
+\362\020\020\234\015\147\174\332\144\040\353\172\060\032\272\110
+\015\170\124\052\231\061\064\253\313\246\152\347\014\147\071\146
+\244\046\250\047\050\347\363\346\074\163\344\053\314\157\061\056
+\023\164\141\313\150\346\322\063\316\122\274\176\145\044\132\041
+\201\061\103\252\262\234\321\030\347\141\074\122\257\200\211\351
+\064\106\336\371\115\231\132\155\035\275\306\045\321\223\125\216
+\370\047\222\103\072\214\225\105\100\343\211\030\247\206\301\131
+\230\312\333\046\034\023\300\214\201\271\230\260\255\151\255\156
+\030\343\173\142\101\365\255\066\376\013\264\173\040\137\237\251
+\156\371\231\202\022\122\322\212\304\124\170\264\174\367\101\233
+\003\347\007\136\263\302\271\111\144\147\222\026\304\140\220\016
+\260\202\175\063\255\320\066\352\321\166\153\174\210\107\230\254
+\033\371\264\120\214\141\201\151\330\061\363\215\372\076\362\365
+\113\257\316\303\035\357\137\050\033\353\030\326\240\130\122\062
+\276\102\157\315\111\227\042\301\160\271\323\343\140\117\336\203
+\202\240\116\060\275\163\123\302\275\027\375\240\300\230\217\352
+\016\027\007\346\103\225\040\116\333\021\250\371\343\323\270\047
+\107\014\047\333\022\353\201\125\314\165\333\237\323\027\103\304
+\373\353\212\050\155\351\257\104\120\132\103\373\361\071\342\223
+\120\317\230\374\104\226\130\070\245\245\355\105\303\122\102\005
+\247\357\345\074\244\254\075\347\326\251\126\005\252\260\303\247
+\031\344\345\075\327\127\104\155\224\021\037\312\160\310\374\271
+\114\314\101\132\203\164\123\220\170\317\326\324\056\117\261\252
+\115\056\365\321\010\133\072\144\357\310\247\250\172\141\354\354
+\246\325\210\116\266\124\324\130\221\302\045\144\221\274\012\024
+\075\222\024\232\265\013\006\351\057\002\003\001\000\001\243\143
+\060\141\060\017\006\003\125\035\023\001\001\377\004\005\060\003
+\001\001\377\060\037\006\003\125\035\043\004\030\060\026\200\024
+\051\202\045\065\012\072\276\222\053\344\011\003\344\354\217\215
+\070\162\071\313\060\035\006\003\125\035\016\004\026\004\024\051
+\202\045\065\012\072\276\222\053\344\011\003\344\354\217\215\070
+\162\071\313\060\016\006\003\125\035\017\001\001\377\004\004\003
+\002\001\206\060\015\006\011\052\206\110\206\367\015\001\001\014
+\005\000\003\202\002\001\000\155\043\206\302\377\365\340\310\300
+\125\212\140\061\314\227\103\107\160\103\323\343\354\122\372\323
+\302\236\373\211\062\032\312\106\223\117\004\227\053\333\320\234
+\204\015\225\007\102\124\376\357\151\041\337\222\003\056\217\067
+\041\043\167\251\167\067\154\240\304\256\234\247\130\071\112\025
+\227\142\106\203\121\040\355\077\302\243\361\303\142\047\320\254
+\023\036\376\074\122\035\220\325\143\361\251\136\352\177\347\347
+\353\226\132\121\354\324\251\033\343\014\224\146\254\313\210\222
+\111\276\163\134\212\340\152\274\246\201\315\263\134\324\043\222
+\310\115\371\040\214\160\224\113\150\155\362\217\036\154\065\367
+\350\137\324\327\275\040\067\122\146\377\053\273\111\146\267\161
+\250\054\137\163\017\007\222\347\116\137\245\006\333\311\212\074
+\227\305\102\352\175\017\201\033\127\353\236\014\017\377\243\047
+\040\111\123\246\263\072\114\313\155\060\065\332\362\360\232\376
+\120\337\155\134\044\075\115\167\152\175\206\137\114\320\341\246
+\264\256\004\023\001\220\361\200\150\204\007\224\202\007\203\353
+\221\345\223\016\165\221\256\243\043\040\111\144\324\272\071\226
+\127\160\356\125\064\050\174\326\257\312\251\236\346\311\001\311
+\007\301\320\104\261\200\264\121\120\252\217\366\234\345\147\163
+\320\033\352\203\065\027\057\120\306\336\126\307\273\243\003\313
+\342\241\030\350\370\316\121\006\243\322\003\100\141\032\247\147
+\127\203\374\321\022\271\050\252\332\116\153\325\234\330\205\067
+\332\275\042\327\064\131\234\032\246\316\170\326\224\170\007\006
+\017\261\223\041\240\111\307\020\236\012\256\121\167\032\371\161
+\220\303\255\230\017\212\051\152\140\001\252\117\255\040\003\055
+\152\216\243\013\152\326\375\223\014\212\141\313\275\050\361\137
+\161\375\270\063\071\326\112\361\366\262\150\122\076\145\217\103
+\235\201\044\044\366\050\114\065\247\375\063\012\245\170\301\004
+\037\354\111\152\304\256\325\104\026\246\247\215\177\332\041\226
+\076\250\272\026\147\324\251\241\347\302\232\370\020\331\073\232
+\356\150\366\057\000\356\313\273\146\215\042\070\206\364\277\137
+\170\251\310\240\035\132\273\165\120\371\122\013\017\035\002\054
+\024\032\363\207\152\167\363
+END
+CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
+CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
+CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
+
+# Trust for "OISTE Client Root RSA G1"
+# Issuer: CN=OISTE Client Root RSA G1,O=OISTE Foundation,C=CH
+# Serial Number:34:17:6f:59:01:88:1b:aa:a5:dd:c8:48:bb:b4:3b:73
+# Subject: CN=OISTE Client Root RSA G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:23:29 2023
+# Not Valid After : Sun May 24 14:23:28 2048
+# Fingerprint (SHA-256): D0:2A:0F:99:4A:86:8C:66:39:5F:2E:7A:88:0D:F5:09:BD:0C:29:C9:6D:E1:60:15:A0:FD:50:1E:DA:4F:96:A9
+# Fingerprint (SHA1): BD:A8:13:20:E0:BF:97:ED:A2:8E:9E:18:5F:F2:D5:FE:E5:2B:13:D5
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Client Root RSA G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\275\250\023\040\340\277\227\355\242\216\236\030\137\362\325\376
+\345\053\023\325
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\232\033\325\012\267\026\352\272\241\212\331\361\036\015\371\023
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\103\154\151\145\156
+\164\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\064\027\157\131\001\210\033\252\245\335\310\110\273\264
+\073\163
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate "OISTE Server Root ECC G1"
+#
+# Issuer: CN=OISTE Server Root ECC G1,O=OISTE Foundation,C=CH
+# Serial Number:23:f9:c3:d6:35:af:8f:28:4b:1f:f0:54:ea:7e:97:9d
+# Subject: CN=OISTE Server Root ECC G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:42:28 2023
+# Not Valid After : Sun May 24 14:42:27 2048
+# Fingerprint (SHA-256): EE:C9:97:C0:C3:0F:21:6F:7E:3B:8B:30:7D:2B:AE:42:41:2D:75:3F:C8:21:9D:AF:D1:52:0B:25:72:85:0F:49
+# Fingerprint (SHA1): 3B:F6:8B:09:AE:2A:92:7B:BA:E3:8D:3F:11:95:D9:E6:44:0C:45:E2
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Server Root ECC G1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\043\371\303\326\065\257\217\050\113\037\360\124\352\176
+\227\235
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\002\065\060\202\001\272\240\003\002\001\002\002\020\043
+\371\303\326\065\257\217\050\113\037\360\124\352\176\227\235\060
+\012\006\010\052\206\110\316\075\004\003\003\060\113\061\013\060
+\011\006\003\125\004\006\023\002\103\110\061\031\060\027\006\003
+\125\004\012\014\020\117\111\123\124\105\040\106\157\165\156\144
+\141\164\151\157\156\061\041\060\037\006\003\125\004\003\014\030
+\117\111\123\124\105\040\123\145\162\166\145\162\040\122\157\157
+\164\040\105\103\103\040\107\061\060\036\027\015\062\063\060\065
+\063\061\061\064\064\062\062\070\132\027\015\064\070\060\065\062
+\064\061\064\064\062\062\067\132\060\113\061\013\060\011\006\003
+\125\004\006\023\002\103\110\061\031\060\027\006\003\125\004\012
+\014\020\117\111\123\124\105\040\106\157\165\156\144\141\164\151
+\157\156\061\041\060\037\006\003\125\004\003\014\030\117\111\123
+\124\105\040\123\145\162\166\145\162\040\122\157\157\164\040\105
+\103\103\040\107\061\060\166\060\020\006\007\052\206\110\316\075
+\002\001\006\005\053\201\004\000\042\003\142\000\004\027\057\372
+\022\274\254\030\363\012\364\104\326\166\102\236\263\350\037\267
+\171\251\130\266\370\145\321\072\041\117\250\353\243\276\244\062
+\162\363\266\001\311\053\375\167\205\156\123\335\255\352\252\056
+\045\222\266\351\041\021\250\257\265\114\013\363\226\140\232\073
+\347\352\032\170\056\264\075\345\050\336\034\200\272\134\156\015
+\333\031\245\343\077\234\052\270\100\113\335\346\117\243\143\060
+\141\060\017\006\003\125\035\023\001\001\377\004\005\060\003\001
+\001\377\060\037\006\003\125\035\043\004\030\060\026\200\024\067
+\115\210\145\317\374\075\212\325\243\361\111\300\116\014\020\157
+\102\264\234\060\035\006\003\125\035\016\004\026\004\024\067\115
+\210\145\317\374\075\212\325\243\361\111\300\116\014\020\157\102
+\264\234\060\016\006\003\125\035\017\001\001\377\004\004\003\002
+\001\206\060\012\006\010\052\206\110\316\075\004\003\003\003\151
+\000\060\146\002\061\000\251\052\060\035\320\302\237\220\121\121
+\100\076\225\124\041\315\026\146\367\123\154\010\026\071\320\022
+\174\177\143\033\337\343\070\000\071\331\055\123\040\105\013\034
+\140\147\061\103\045\355\002\061\000\222\211\256\351\134\142\203
+\142\141\371\055\127\253\126\271\021\335\045\276\152\116\112\032
+\202\153\334\317\323\274\112\263\074\327\056\233\333\370\050\151
+\274\153\055\354\061\241\072\343\127
+END
+CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
+CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
+CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
+
+# Trust for "OISTE Server Root ECC G1"
+# Issuer: CN=OISTE Server Root ECC G1,O=OISTE Foundation,C=CH
+# Serial Number:23:f9:c3:d6:35:af:8f:28:4b:1f:f0:54:ea:7e:97:9d
+# Subject: CN=OISTE Server Root ECC G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:42:28 2023
+# Not Valid After : Sun May 24 14:42:27 2048
+# Fingerprint (SHA-256): EE:C9:97:C0:C3:0F:21:6F:7E:3B:8B:30:7D:2B:AE:42:41:2D:75:3F:C8:21:9D:AF:D1:52:0B:25:72:85:0F:49
+# Fingerprint (SHA1): 3B:F6:8B:09:AE:2A:92:7B:BA:E3:8D:3F:11:95:D9:E6:44:0C:45:E2
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 "OISTE Server Root ECC G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\073\366\213\011\256\052\222\173\272\343\215\077\021\225\331\346
+\104\014\105\342
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\102\247\322\065\256\002\222\333\031\166\010\336\057\005\264\324
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\105\103\103\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\043\371\303\326\065\257\217\050\113\037\360\124\352\176
+\227\235
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
+
+#
+# Certificate " OISTE Server Root RSA G1"
+#
+# Issuer: CN=OISTE Server Root RSA G1,O=OISTE Foundation,C=CH
+# Serial Number:55:a5:d9:67:94:28:c6:ed:0c:fa:27:dd:5b:01:4d:18
+# Subject: CN=OISTE Server Root RSA G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:37:16 2023
+# Not Valid After : Sun May 24 14:37:15 2048
+# Fingerprint (SHA-256): 9A:E3:62:32:A5:18:9F:FD:DB:35:3D:FD:26:52:0C:01:53:95:D2:27:77:DA:C5:9D:B5:7B:98:C0:89:A6:51:E6
+# Fingerprint (SHA1): F7:00:34:25:94:88:68:31:E4:34:87:3F:70:FE:86:B3:86:9F:F0:6E
+CKA_CLASS CK_OBJECT_CLASS CKO_CERTIFICATE
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 " OISTE Server Root RSA G1"
+CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE CKC_X_509
+CKA_SUBJECT MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_ID UTF8 "0"
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\125\245\331\147\224\050\306\355\014\372\047\335\133\001
+\115\030
+END
+CKA_VALUE MULTILINE_OCTAL
+\060\202\005\203\060\202\003\153\240\003\002\001\002\002\020\125
+\245\331\147\224\050\306\355\014\372\047\335\133\001\115\030\060
+\015\006\011\052\206\110\206\367\015\001\001\014\005\000\060\113
+\061\013\060\011\006\003\125\004\006\023\002\103\110\061\031\060
+\027\006\003\125\004\012\014\020\117\111\123\124\105\040\106\157
+\165\156\144\141\164\151\157\156\061\041\060\037\006\003\125\004
+\003\014\030\117\111\123\124\105\040\123\145\162\166\145\162\040
+\122\157\157\164\040\122\123\101\040\107\061\060\036\027\015\062
+\063\060\065\063\061\061\064\063\067\061\066\132\027\015\064\070
+\060\065\062\064\061\064\063\067\061\065\132\060\113\061\013\060
+\011\006\003\125\004\006\023\002\103\110\061\031\060\027\006\003
+\125\004\012\014\020\117\111\123\124\105\040\106\157\165\156\144
+\141\164\151\157\156\061\041\060\037\006\003\125\004\003\014\030
+\117\111\123\124\105\040\123\145\162\166\145\162\040\122\157\157
+\164\040\122\123\101\040\107\061\060\202\002\042\060\015\006\011
+\052\206\110\206\367\015\001\001\001\005\000\003\202\002\017\000
+\060\202\002\012\002\202\002\001\000\252\256\364\253\202\317\373
+\345\067\013\347\325\226\255\220\350\113\051\334\125\140\343\314
+\274\263\274\055\222\271\344\243\172\361\201\264\236\162\162\103
+\337\077\253\013\046\264\356\173\032\151\373\050\320\162\134\112
+\155\151\231\360\143\036\014\322\261\377\326\214\064\320\356\333
+\254\110\271\352\260\024\216\330\007\251\044\230\335\351\011\276
+\250\042\033\131\071\321\047\207\334\034\315\370\373\263\353\351
+\223\170\355\017\316\067\174\046\167\156\241\330\054\041\114\344
+\212\117\307\023\074\156\307\325\023\227\262\250\333\044\151\203
+\126\323\151\313\202\022\273\235\033\362\370\064\362\230\053\052
+\216\004\147\366\343\207\241\035\255\156\316\066\164\016\136\063
+\073\313\333\121\227\224\152\225\074\316\030\132\156\113\306\374
+\007\217\056\032\271\112\367\144\064\051\334\246\215\120\341\215
+\213\113\345\110\033\156\056\200\020\077\344\237\033\145\077\021
+\264\352\127\151\237\264\000\353\205\044\231\044\365\041\235\227
+\252\373\064\177\002\153\025\220\255\273\236\132\031\177\244\214
+\330\372\155\050\374\070\307\343\114\255\152\316\331\116\223\222
+\216\314\014\147\277\013\113\226\316\146\147\123\150\313\027\021
+\216\131\367\254\234\033\271\216\150\104\267\030\257\346\345\017
+\145\334\225\011\260\223\022\265\037\076\224\245\307\210\165\041
+\261\336\011\044\052\114\342\274\354\114\147\107\302\051\210\271
+\012\272\371\301\164\316\214\030\046\145\332\367\157\306\214\173
+\150\134\013\356\143\300\136\113\361\116\314\237\057\017\341\350
+\232\172\223\361\340\310\333\277\047\346\145\051\173\066\340\063
+\025\163\362\235\153\204\010\150\053\066\007\053\047\314\170\330
+\152\207\016\107\164\364\252\240\023\135\144\176\364\333\024\256
+\373\072\344\057\301\145\343\271\172\100\154\360\006\267\173\050
+\233\327\341\137\070\163\224\254\331\160\223\055\334\204\257\106
+\034\242\172\054\077\201\046\102\347\324\330\305\154\204\146\021
+\213\167\153\124\034\243\265\330\020\360\256\051\367\147\010\210
+\027\134\270\227\171\317\352\053\052\356\130\063\345\155\351\051
+\252\145\001\015\202\023\354\045\013\135\054\100\162\025\051\323
+\220\054\367\032\103\325\152\360\151\002\003\001\000\001\243\143
+\060\141\060\017\006\003\125\035\023\001\001\377\004\005\060\003
+\001\001\377\060\037\006\003\125\035\043\004\030\060\026\200\024
+\362\311\301\017\015\143\000\273\354\105\016\112\037\265\261\263
+\066\315\016\215\060\035\006\003\125\035\016\004\026\004\024\362
+\311\301\017\015\143\000\273\354\105\016\112\037\265\261\263\066
+\315\016\215\060\016\006\003\125\035\017\001\001\377\004\004\003
+\002\001\206\060\015\006\011\052\206\110\206\367\015\001\001\014
+\005\000\003\202\002\001\000\064\147\171\262\072\306\345\075\367
+\043\162\271\011\357\222\255\047\037\240\116\012\262\365\332\027
+\014\242\205\322\176\222\121\375\025\145\327\134\153\144\026\356
+\212\105\312\014\103\066\104\065\331\177\376\171\072\034\350\306
+\344\075\153\167\324\041\020\343\366\363\040\116\251\276\211\363
+\034\234\251\337\274\060\072\027\321\062\103\320\252\212\162\034
+\121\050\114\335\066\310\344\055\147\175\221\207\034\235\274\374
+\253\050\226\136\141\134\270\042\063\030\110\026\120\352\312\057
+\351\245\111\334\177\074\244\031\274\066\255\222\342\271\364\113
+\325\353\010\255\347\170\376\027\300\135\207\167\350\147\167\117
+\000\146\257\364\261\003\072\276\022\174\101\065\345\364\246\033
+\107\213\313\171\367\326\277\027\156\116\145\360\370\332\127\301
+\224\201\345\172\126\015\273\106\177\157\221\375\175\346\027\344
+\201\047\273\005\210\126\335\040\245\367\230\055\221\031\151\061
+\137\233\060\362\231\255\162\100\226\314\330\167\146\233\264\325
+\016\262\020\376\024\252\303\200\161\235\075\215\350\175\024\154
+\141\144\206\106\246\327\124\305\266\327\220\026\106\245\205\312
+\236\072\343\346\023\026\266\025\043\314\251\051\122\375\000\306
+\366\220\216\126\217\211\010\335\226\252\346\323\152\251\206\065
+\366\325\105\170\102\112\106\374\003\310\136\330\146\366\105\145
+\044\264\276\207\173\125\040\235\367\235\265\052\374\271\142\031
+\313\154\073\257\323\155\070\154\253\173\246\036\215\374\351\236
+\376\153\025\271\333\202\232\313\230\337\163\241\220\240\240\305
+\340\350\001\250\243\024\234\310\301\232\254\025\120\063\215\355
+\174\052\213\163\225\100\103\046\374\201\244\052\137\071\220\267
+\047\313\121\167\370\226\223\036\317\362\167\175\037\106\223\242
+\131\036\225\104\305\055\165\144\260\326\371\340\074\151\352\004
+\265\034\013\342\106\104\115\103\073\227\111\161\021\275\044\266
+\302\255\162\124\006\376\153\030\371\167\333\051\054\122\236\155
+\167\173\142\375\017\115\216\230\062\060\060\161\022\326\045\065
+\343\237\370\157\234\265\353\152\033\255\352\020\323\226\026\162
+\006\041\045\306\114\274\217\160\273\014\344\136\042\203\055\322
+\276\376\205\133\264\344\275
+END
+CKA_NSS_MOZILLA_CA_POLICY CK_BBOOL CK_TRUE
+CKA_NSS_SERVER_DISTRUST_AFTER CK_BBOOL CK_FALSE
+CKA_NSS_EMAIL_DISTRUST_AFTER CK_BBOOL CK_FALSE
+
+# Trust for " OISTE Server Root RSA G1"
+# Issuer: CN=OISTE Server Root RSA G1,O=OISTE Foundation,C=CH
+# Serial Number:55:a5:d9:67:94:28:c6:ed:0c:fa:27:dd:5b:01:4d:18
+# Subject: CN=OISTE Server Root RSA G1,O=OISTE Foundation,C=CH
+# Not Valid Before: Wed May 31 14:37:16 2023
+# Not Valid After : Sun May 24 14:37:15 2048
+# Fingerprint (SHA-256): 9A:E3:62:32:A5:18:9F:FD:DB:35:3D:FD:26:52:0C:01:53:95:D2:27:77:DA:C5:9D:B5:7B:98:C0:89:A6:51:E6
+# Fingerprint (SHA1): F7:00:34:25:94:88:68:31:E4:34:87:3F:70:FE:86:B3:86:9F:F0:6E
+CKA_CLASS CK_OBJECT_CLASS CKO_NSS_TRUST
+CKA_TOKEN CK_BBOOL CK_TRUE
+CKA_PRIVATE CK_BBOOL CK_FALSE
+CKA_MODIFIABLE CK_BBOOL CK_FALSE
+CKA_LABEL UTF8 " OISTE Server Root RSA G1"
+CKA_CERT_SHA1_HASH MULTILINE_OCTAL
+\367\000\064\045\224\210\150\061\344\064\207\077\160\376\206\263
+\206\237\360\156
+END
+CKA_CERT_MD5_HASH MULTILINE_OCTAL
+\043\247\236\324\160\270\271\024\127\101\212\176\104\131\342\150
+END
+CKA_ISSUER MULTILINE_OCTAL
+\060\113\061\013\060\011\006\003\125\004\006\023\002\103\110\061
+\031\060\027\006\003\125\004\012\014\020\117\111\123\124\105\040
+\106\157\165\156\144\141\164\151\157\156\061\041\060\037\006\003
+\125\004\003\014\030\117\111\123\124\105\040\123\145\162\166\145
+\162\040\122\157\157\164\040\122\123\101\040\107\061
+END
+CKA_SERIAL_NUMBER MULTILINE_OCTAL
+\002\020\125\245\331\147\224\050\306\355\014\372\047\335\133\001
+\115\030
+END
+CKA_TRUST_SERVER_AUTH CK_TRUST CKT_NSS_TRUSTED_DELEGATOR
+CKA_TRUST_EMAIL_PROTECTION CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_CODE_SIGNING CK_TRUST CKT_NSS_MUST_VERIFY_TRUST
+CKA_TRUST_STEP_UP_APPROVED CK_BBOOL CK_FALSE
diff --git a/packages/bun-usockets/src/crypto/openssl.c b/packages/bun-usockets/src/crypto/openssl.c
index 60e1900da5..348819d0e8 100644
--- a/packages/bun-usockets/src/crypto/openssl.c
+++ b/packages/bun-usockets/src/crypto/openssl.c
@@ -635,7 +635,7 @@ ssl_on_writable(struct us_internal_ssl_socket_t *s) {
(struct us_internal_ssl_socket_context_t *)us_socket_context(0, &s->s);
// if this one fails to write data, it sets ssl_read_wants_write again
- s = (struct us_internal_ssl_socket_t *)context->sc.on_data(&s->s, 0,
+ s = (struct us_internal_ssl_socket_t *)context->sc.on_data(&s->s, "",
0); // cast here!
}
// Do not call on_writable if the socket is closed.
diff --git a/packages/bun-usockets/src/crypto/root_certs.h b/packages/bun-usockets/src/crypto/root_certs.h
index 7ba5d4f935..552e1bd0fa 100644
--- a/packages/bun-usockets/src/crypto/root_certs.h
+++ b/packages/bun-usockets/src/crypto/root_certs.h
@@ -3570,4 +3570,50 @@ static struct us_cert_string_t root_certs[] = {
"A4GzJl5LuEsAz/+MF7psYC0nhzck5npgL7XTgwSqT0N1osGDsieYK7EOgLrAhV5Cud+xYJHT\n"
"6xh+cHiudoO+cVrQkOPKwRYlZ0rwtnu64ZzZ\n"
"-----END CERTIFICATE-----",.len=1988},
+
+/* OISTE Server Root ECC G1 */
+{.str="-----BEGIN CERTIFICATE-----\n"
+"MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQswCQYDVQQG\n"
+"EwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2VydmVy\n"
+"IFJvb3QgRUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUyNDE0NDIyN1owSzELMAkGA1UE\n"
+"BhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZl\n"
+"ciBSb290IEVDQyBHMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPo\n"
+"H7d5qVi2+GXROiFPqOujvqQycvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4\n"
+"LrQ95SjeHIC6XG4N2xml4z+cKrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSME\n"
+"GDAWgBQ3TYhlz/w9itWj8UnATgwQb0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9C\n"
+"tJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYCMQCpKjAd0MKfkFFRQD6VVCHN\n"
+"Fmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxgZzFDJe0CMQCSia7pXGKDYmH5LVerVrkR3SW+\n"
+"ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c=\n"
+"-----END CERTIFICATE-----",.len=824},
+
+/* OISTE Server Root RSA G1 */
+{.str="-----BEGIN CERTIFICATE-----\n"
+"MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBLMQswCQYD\n"
+"VQQGEwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2Vy\n"
+"dmVyIFJvb3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4MDUyNDE0MzcxNVowSzELMAkG\n"
+"A1UEBhMCQ0gxGTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNl\n"
+"cnZlciBSb290IFJTQSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuC\n"
+"z/vlNwvn1ZatkOhLKdxVYOPMvLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnw\n"
+"Yx4M0rH/1ow00O7brEi56rAUjtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8Jndu\n"
+"odgsIUzkik/HEzxux9UTl7Ko2yRpg1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4z\n"
+"O8vbUZeUapU8zhhabkvG/AePLhq5SvdkNCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8RtOpXaZ+0\n"
+"AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY+m0o/DjH40ytas7ZTpOSjswMZ78LS5bOZmdT\n"
+"aMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+lKXHiHUhsd4JJCpM4rzsTGdHwimIuQq6\n"
+"+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+HomnqT8eDI278n5mUpezbgMxVz8p1rhAho\n"
+"KzYHKyfMeNhqhw5HdPSqoBNdZH702xSu+zrkL8Fl47l6QGzwBrd7KJvX4V84c5Ss2XCTLdyE\n"
+"r0YconosP4EmQufU2MVshGYRi3drVByjtdgQ8K4p92cIiBdcuJd5z+orKu5YM+Vt6SmqZQEN\n"
+"ghPsJQtdLEByFSnTkCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j\n"
+"BBgwFoAU8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC77EUOSh+1sbM2\n"
+"zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33I3K5Ce+S\n"
+"rScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG5D1rd9QhEOP28yBO\n"
+"qb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8qyiWXmFcuCIzGEgWUOrKL+ml\n"
+"Sdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dPAGav9LEDOr4SfEE15fSmG0eLy3n31r8X\n"
+"bk5l8PjaV8GUgeV6Vg27Rn9vkf195hfkgSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2ab\n"
+"tNUOshD+FKrDgHGdPY3ofRRsYWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5W\n"
+"j4kI3Zaq5tNqqYY19tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7\n"
+"ph6N/Ome/msVuduCmsuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3\n"
+"J8tRd/iWkx7P8nd9H0aTolkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2wq1yVAb+\n"
+"axj5d9spLFKebXd7Yv0PTY6YMjAwcRLWJTXjn/hvnLXrahut6hDTlhZyBiElxky8j3C7DORe\n"
+"IoMt0r7+hVu05L0=\n"
+"-----END CERTIFICATE-----",.len=1968},
};
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index ead3de99c8..7bc2a53ad6 100755
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -1392,6 +1392,10 @@ create_buildkite_user() {
create_file "$file"
done
+ # The following is necessary to configure buildkite to use a stable
+ # checkout directory. sccache hashes absolute paths into its cache keys,
+ # so if buildkite uses a different checkout path each time (which it does
+ # by default), sccache will be useless.
local opts=$-
set -ef
diff --git a/src/Progress.zig b/src/Progress.zig
index 55777fde8a..1536bacc47 100644
--- a/src/Progress.zig
+++ b/src/Progress.zig
@@ -71,7 +71,7 @@ pub const Node = struct {
context: *Progress,
parent: ?*Node,
name: []const u8,
- unit: []const u8 = "",
+ unit: enum { none, files, bytes } = .none,
/// Must be handled atomically to be thread-safe.
recently_updated_child: ?*Node = null,
/// Must be handled atomically to be thread-safe. 0 means null.
@@ -326,16 +326,18 @@ fn refreshWithHeldLock(self: *Progress) void {
}
if (eti > 0) {
if (need_ellipse) self.bufWrite(&end, " ", .{});
- switch (node.unit.len == 0) {
- true => self.bufWrite(&end, "[{Bi:.2}/{Bi:.2}] ", .{ current_item, eti }),
- false => self.bufWrite(&end, "[{d}/{d}{s}] ", .{ current_item, eti, node.unit }),
+ switch (node.unit) {
+ .none => self.bufWrite(&end, "[{d}/{d}] ", .{ current_item, eti }),
+ .files => self.bufWrite(&end, "[{d}/{d} files] ", .{ current_item, eti }),
+ .bytes => self.bufWrite(&end, "[{Bi:.2}/{Bi:.2}] ", .{ current_item, eti }),
}
need_ellipse = false;
} else if (completed_items != 0) {
if (need_ellipse) self.bufWrite(&end, " ", .{});
- switch (node.unit.len == 0) {
- true => self.bufWrite(&end, "[{Bi:.2}] ", .{current_item}),
- false => self.bufWrite(&end, "[{d}{s}] ", .{ current_item, node.unit }),
+ switch (node.unit) {
+ .none => self.bufWrite(&end, "[{d}] ", .{current_item}),
+ .files => self.bufWrite(&end, "[{d} files] ", .{current_item}),
+ .bytes => self.bufWrite(&end, "[{Bi:.2}] ", .{current_item}),
}
need_ellipse = false;
}
diff --git a/src/bake/DevServer/SerializedFailure.zig b/src/bake/DevServer/SerializedFailure.zig
index d14af1c133..9ee733aa89 100644
--- a/src/bake/DevServer/SerializedFailure.zig
+++ b/src/bake/DevServer/SerializedFailure.zig
@@ -104,29 +104,6 @@ pub const ErrorKind = enum(u8) {
js_aggregate,
};
-pub fn initFromJs(dev: *DevServer, owner: Owner, value: JSValue) !SerializedFailure {
- {
- _ = value;
- @panic("TODO");
- }
- // Avoid small re-allocations without requesting so much from the heap
- var sfb = std.heap.stackFallback(65536, dev.allocator());
- var payload = std.array_list.Managed(u8).initCapacity(sfb.get(), 65536) catch
- unreachable; // enough space
- const w = payload.writer();
-
- try w.writeInt(u32, @bitCast(owner.encode()), .little);
- // try writeJsValue(value);
-
- // Avoid-recloning if it is was moved to the hap
- const data = if (payload.items.ptr == &sfb.buffer)
- try dev.allocator().dupe(u8, payload.items)
- else
- payload.items;
-
- return .{ .data = data };
-}
-
pub fn initFromLog(
dev: *DevServer,
owner: Owner,
diff --git a/src/bun.js/api/bun/h2_frame_parser.zig b/src/bun.js/api/bun/h2_frame_parser.zig
index 4e7f86db3b..de5f88a2a9 100644
--- a/src/bun.js/api/bun/h2_frame_parser.zig
+++ b/src/bun.js/api/bun/h2_frame_parser.zig
@@ -3028,7 +3028,7 @@ pub const H2FrameParser = struct {
var stream = this.streams.getPtr(stream_id) orelse {
return globalObject.throw("Invalid stream id", .{});
};
- var state = jsc.JSValue.createEmptyObject(globalObject, 7);
+ var state = jsc.JSValue.createEmptyObject(globalObject, 6);
state.put(globalObject, jsc.ZigString.static("localWindowSize"), jsc.JSValue.jsNumber(stream.windowSize));
state.put(globalObject, jsc.ZigString.static("state"), jsc.JSValue.jsNumber(@intFromEnum(stream.state)));
diff --git a/src/bun.js/api/bun/socket/tls_socket_functions.zig b/src/bun.js/api/bun/socket/tls_socket_functions.zig
index 1c8ea80325..1330d208d1 100644
--- a/src/bun.js/api/bun/socket/tls_socket_functions.zig
+++ b/src/bun.js/api/bun/socket/tls_socket_functions.zig
@@ -383,9 +383,9 @@ pub fn getEphemeralKeyInfo(this: *This, globalObject: *jsc.JSGlobalObject, _: *j
if (this.isServer()) {
return JSValue.jsNull();
}
- var result = JSValue.createEmptyObject(globalObject, 3);
const ssl_ptr = this.socket.ssl() orelse return JSValue.jsNull();
+ var result = JSValue.createEmptyObject(globalObject, 0);
// TODO: investigate better option or compatible way to get the key
// this implementation follows nodejs but for BoringSSL SSL_get_server_tmp_key will always return 0
diff --git a/src/bun.js/node/node_os.zig b/src/bun.js/node/node_os.zig
index 9da343a975..f4bd9eee52 100644
--- a/src/bun.js/node/node_os.zig
+++ b/src/bun.js/node/node_os.zig
@@ -92,7 +92,7 @@ fn cpusImplLinux(globalThis: *jsc.JSGlobalObject) !jsc.JSValue {
times.irq = scale * try std.fmt.parseInt(u64, toks.next() orelse return error.eol, 10);
// Actually create the JS object representing the CPU
- const cpu = jsc.JSValue.createEmptyObject(globalThis, 3);
+ const cpu = jsc.JSValue.createEmptyObject(globalThis, 1);
cpu.put(globalThis, jsc.ZigString.static("times"), times.toValue(globalThis));
try values.putIndex(globalThis, num_cpus, cpu);
@@ -511,7 +511,7 @@ fn networkInterfacesPosix(globalThis: *jsc.JSGlobalObject) bun.JSError!jsc.JSVal
num_inet_interfaces += 1;
}
- var ret = jsc.JSValue.createEmptyObject(globalThis, 8);
+ var ret = jsc.JSValue.createEmptyObject(globalThis, 0);
// Second pass through, populate each interface object
it = interface_start;
@@ -522,7 +522,7 @@ fn networkInterfacesPosix(globalThis: *jsc.JSGlobalObject) bun.JSError!jsc.JSVal
const addr = std.net.Address.initPosix(@alignCast(@as(*std.posix.sockaddr, @ptrCast(iface.ifa_addr))));
const netmask = std.net.Address.initPosix(@alignCast(@as(*std.posix.sockaddr, @ptrCast(iface.ifa_netmask))));
- var interface = jsc.JSValue.createEmptyObject(globalThis, 7);
+ var interface = jsc.JSValue.createEmptyObject(globalThis, 0);
// address The assigned IPv4 or IPv6 address
// cidr The assigned IPv4 or IPv6 address with the routing prefix in CIDR notation. If the netmask is invalid, this property is set to null.
diff --git a/src/cli/pack_command.zig b/src/cli/pack_command.zig
index 5774b0795d..daaf8f8881 100644
--- a/src/cli/pack_command.zig
+++ b/src/cli/pack_command.zig
@@ -1638,7 +1638,7 @@ pub const PackCommand = struct {
progress = .{};
progress.supports_ansi_escape_codes = Output.enable_ansi_colors_stderr;
node = progress.start("", pack_queue.count() + bundled_pack_queue.count() + 1);
- node.unit = " files";
+ node.unit = .files;
}
defer if (log_level.showProgress()) node.end();
diff --git a/src/cli/upgrade_command.zig b/src/cli/upgrade_command.zig
index 6064121e4c..607ad8f533 100644
--- a/src/cli/upgrade_command.zig
+++ b/src/cli/upgrade_command.zig
@@ -422,6 +422,7 @@ pub const UpgradeCommand = struct {
{
var refresher = Progress{};
var progress = refresher.start("Downloading", version.size);
+ progress.unit = .bytes;
refresher.refresh();
var async_http = try ctx.allocator.create(HTTP.AsyncHTTP);
var zip_file_buffer = try ctx.allocator.create(MutableString);
diff --git a/src/deps/uws/socket.zig b/src/deps/uws/socket.zig
index 61e378da82..bab59f189c 100644
--- a/src/deps/uws/socket.zig
+++ b/src/deps/uws/socket.zig
@@ -183,7 +183,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type {
const res = Fields.onData(
getValue(socket),
TLSSocket.from(socket),
- buf.?[0..@as(usize, @intCast(len))],
+ if (buf) |data_ptr| data_ptr[0..@as(usize, @intCast(len))] else "",
);
if (@TypeOf(res) != void) res catch |err| switch (err) {
error.JSTerminated => return null, // TODO: declare throw scope
@@ -744,7 +744,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type {
const res = Fields.onData(
getValue(socket),
SocketHandlerType.from(socket),
- buf.?[0..@as(usize, @intCast(len))],
+ if (buf) |data_ptr| data_ptr[0..@as(usize, @intCast(len))] else "",
);
if (@TypeOf(res) != void) res catch |err| switch (err) {
error.JSTerminated => return null, // TODO: declare throw scope
@@ -910,7 +910,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type {
const res = Fields.onData(
getValue(socket),
ThisSocket.from(socket),
- buf.?[0..@as(usize, @intCast(len))],
+ if (buf) |data_ptr| data_ptr[0..@as(usize, @intCast(len))] else "",
);
if (@TypeOf(res) != void) res catch |err| switch (err) {
error.JSTerminated => return null, // TODO: declare throw scope
diff --git a/src/s3/list_objects.zig b/src/s3/list_objects.zig
index 9238719d3b..c862041588 100644
--- a/src/s3/list_objects.zig
+++ b/src/s3/list_objects.zig
@@ -118,7 +118,7 @@ pub const S3ListObjectsV2Result = struct {
const jsContents = try JSValue.createEmptyArray(globalObject, contents.items.len);
for (contents.items, 0..) |item, i| {
- const objectInfo = JSValue.createEmptyObject(globalObject, 1);
+ const objectInfo = JSValue.createEmptyObject(globalObject, 0);
objectInfo.put(globalObject, jsc.ZigString.static("key"), try bun.String.createUTF8ForJS(globalObject, item.key));
if (item.etag) |etag| {
@@ -146,7 +146,7 @@ pub const S3ListObjectsV2Result = struct {
}
if (item.owner) |owner| {
- const jsOwner = JSValue.createEmptyObject(globalObject, 2);
+ const jsOwner = JSValue.createEmptyObject(globalObject, 0);
if (owner.id) |id| {
jsOwner.put(globalObject, jsc.ZigString.static("id"), try bun.String.createUTF8ForJS(globalObject, id));
}
@@ -168,7 +168,7 @@ pub const S3ListObjectsV2Result = struct {
const jsCommonPrefixes = try JSValue.createEmptyArray(globalObject, common_prefixes.items.len);
for (common_prefixes.items, 0..) |prefix, i| {
- const jsPrefix = JSValue.createEmptyObject(globalObject, 1);
+ const jsPrefix = JSValue.createEmptyObject(globalObject, 0);
jsPrefix.put(globalObject, jsc.ZigString.static("prefix"), try bun.String.createUTF8ForJS(globalObject, prefix));
try jsCommonPrefixes.putIndex(globalObject, @intCast(i), jsPrefix);
}