bun-types
Advanced tools
Comparing version
@@ -114,2 +114,34 @@ Bun implements the WHATWG `fetch` standard, with some extensions to meet the needs of server-side JavaScript. | ||
### Streaming request bodies | ||
You can also stream data in request bodies using a `ReadableStream`: | ||
```ts | ||
const stream = new ReadableStream({ | ||
start(controller) { | ||
controller.enqueue("Hello"); | ||
controller.enqueue(" "); | ||
controller.enqueue("World"); | ||
controller.close(); | ||
}, | ||
}); | ||
const response = await fetch("http://example.com", { | ||
method: "POST", | ||
body: stream, | ||
}); | ||
``` | ||
When using streams with HTTP(S): | ||
- The data is streamed directly to the network without buffering the entire body in memory | ||
- If the connection is lost, the stream will be canceled | ||
- The `Content-Length` header is not automatically set unless the stream has a known size | ||
When using streams with S3: | ||
- For PUT/POST requests, Bun automatically uses multipart upload | ||
- The stream is consumed in chunks and uploaded in parallel | ||
- Progress can be monitored through the S3 options | ||
### Fetching a URL with a timeout | ||
@@ -184,2 +216,112 @@ | ||
#### Disable TLS validation | ||
To disable TLS validation, set `rejectUnauthorized` to `false`: | ||
```ts | ||
await fetch("https://example.com", { | ||
tls: { | ||
rejectUnauthorized: false, | ||
}, | ||
}); | ||
``` | ||
This is especially useful to avoid SSL errors when using self-signed certificates, but this disables TLS validation and should be used with caution. | ||
### Request options | ||
In addition to the standard fetch options, Bun provides several extensions: | ||
```ts | ||
const response = await fetch("http://example.com", { | ||
// Control automatic response decompression (default: true) | ||
decompress: true, | ||
// Disable connection reuse for this request | ||
keepalive: false, | ||
// Debug logging level | ||
verbose: true, // or "curl" for more detailed output | ||
}); | ||
``` | ||
### Protocol support | ||
Beyond HTTP(S), Bun's fetch supports several additional protocols: | ||
#### S3 URLs - `s3://` | ||
Bun supports fetching from S3 buckets directly. | ||
```ts | ||
// Using environment variables for credentials | ||
const response = await fetch("s3://my-bucket/path/to/object"); | ||
// Or passing credentials explicitly | ||
const response = await fetch("s3://my-bucket/path/to/object", { | ||
s3: { | ||
accessKeyId: "YOUR_ACCESS_KEY", | ||
secretAccessKey: "YOUR_SECRET_KEY", | ||
region: "us-east-1", | ||
}, | ||
}); | ||
``` | ||
Note: Only PUT and POST methods support request bodies when using S3. For uploads, Bun automatically uses multipart upload for streaming bodies. | ||
You can read more about Bun's S3 support in the [S3](https://bun.sh/docs/api/s3) documentation. | ||
#### File URLs - `file://` | ||
You can fetch local files using the `file:` protocol: | ||
```ts | ||
const response = await fetch("file:///path/to/file.txt"); | ||
const text = await response.text(); | ||
``` | ||
On Windows, paths are automatically normalized: | ||
```ts | ||
// Both work on Windows | ||
const response = await fetch("file:///C:/path/to/file.txt"); | ||
const response2 = await fetch("file:///c:/path\\to/file.txt"); | ||
``` | ||
#### Data URLs - `data:` | ||
Bun supports the `data:` URL scheme: | ||
```ts | ||
const response = await fetch("data:text/plain;base64,SGVsbG8sIFdvcmxkIQ=="); | ||
const text = await response.text(); // "Hello, World!" | ||
``` | ||
#### Blob URLs - `blob:` | ||
You can fetch blobs using URLs created by `URL.createObjectURL()`: | ||
```ts | ||
const blob = new Blob(["Hello, World!"], { type: "text/plain" }); | ||
const url = URL.createObjectURL(blob); | ||
const response = await fetch(url); | ||
``` | ||
### Error handling | ||
Bun's fetch implementation includes several specific error cases: | ||
- Using a request body with GET/HEAD methods will throw an error (which is expected for the fetch API) | ||
- Attempting to use both `proxy` and `unix` options together will throw an error | ||
- TLS certificate validation failures when `rejectUnauthorized` is true (or undefined) | ||
- S3 operations may throw specific errors related to authentication or permissions | ||
### Content-Type handling | ||
Bun automatically sets the `Content-Type` header for request bodies when not explicitly provided: | ||
- For `Blob` objects, uses the blob's `type` | ||
- For `FormData`, sets appropriate multipart boundary | ||
- For JSON objects, sets `application/json` | ||
## Debugging | ||
@@ -200,3 +342,3 @@ | ||
[fetch] > Connection: keep-alive | ||
[fetch] > User-Agent: Bun/bun-v1.2.1 | ||
[fetch] > User-Agent: Bun/1.2.2-canary.20250201T140531 | ||
[fetch] > Accept: */* | ||
@@ -312,1 +454,14 @@ [fetch] > Host: example.com | ||
``` | ||
### Implementation details | ||
- Connection pooling is enabled by default but can be disabled per-request with `keepalive: false`. The `"Connection: close"` header can also be used to disable keep-alive. | ||
- Large file uploads are optimized using the operating system's `sendfile` syscall under specific conditions: | ||
- The file must be larger than 32KB | ||
- The request must not be using a proxy | ||
- On macOS, only regular files (not pipes, sockets, or devices) can use `sendfile` | ||
- When these conditions aren't met, or when using S3/streaming uploads, Bun falls back to reading the file into memory | ||
- This optimization is particularly effective for HTTP (not HTTPS) requests where the file can be sent directly from the kernel to the network stack | ||
- S3 operations automatically handle signing requests and merging authentication headers | ||
Note: Many of these features are Bun-specific extensions to the standard fetch API. |
@@ -516,2 +516,237 @@ The page primarily documents the Bun-native `Bun.serve` API. Bun also implements [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and the Node.js [`http`](https://nodejs.org/api/http.html) and [`https`](https://nodejs.org/api/https.html) modules. | ||
## Server Lifecycle Methods | ||
### server.stop() - Stop the server | ||
To stop the server from accepting new connections: | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req) { | ||
return new Response("Hello!"); | ||
}, | ||
}); | ||
// Gracefully stop the server (waits for in-flight requests) | ||
await server.stop(); | ||
// Force stop and close all active connections | ||
await server.stop(true); | ||
``` | ||
By default, `stop()` allows in-flight requests and WebSocket connections to complete. Pass `true` to immediately terminate all connections. | ||
### server.ref() and server.unref() - Process lifecycle control | ||
Control whether the server keeps the Bun process alive: | ||
```ts | ||
// Don't keep process alive if server is the only thing running | ||
server.unref(); | ||
// Restore default behavior - keep process alive | ||
server.ref(); | ||
``` | ||
### server.reload() - Hot reload handlers | ||
Update the server's handlers without restarting: | ||
```ts | ||
const server = Bun.serve({ | ||
static: { | ||
"/api/version": Response.json({ version: "v1" }), | ||
}, | ||
fetch(req) { | ||
return new Response("v1"); | ||
}, | ||
}); | ||
// Update to new handler | ||
server.reload({ | ||
static: { | ||
"/api/version": Response.json({ version: "v2" }), | ||
}, | ||
fetch(req) { | ||
return new Response("v2"); | ||
}, | ||
}); | ||
``` | ||
This is useful for development and hot reloading. Only `fetch`, `error`, and `static` handlers can be updated. | ||
## Per-Request Controls | ||
<!-- ### server.abort(Request) - Abort requests | ||
The `server.abort(request: Request)` method: | ||
- Returns `true` if request was aborted, `false` if already aborted/completed | ||
- Triggers the request's `AbortSignal` | ||
- Cancels any attached `ReadableStream` | ||
- Rejects any pending body promises (like `.text()`) | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req, server) { | ||
// abort if the url contains "slow" | ||
if (req.url.includes("slow")) { | ||
server.abort(req); | ||
// When aborted, the server will not error due to the lack of a `Response` object | ||
// If you return a `Response` anyway, it will be ignored. | ||
return; | ||
} | ||
return new Response("Processing..."); | ||
}, | ||
}); | ||
``` --> | ||
### server.timeout(Request, seconds) - Custom request timeouts | ||
Set a custom idle timeout for individual requests: | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req, server) { | ||
// Set 60 second timeout for this request | ||
server.timeout(req, 60); | ||
// If they take longer than 60 seconds to send the body, the request will be aborted | ||
await req.text(); | ||
return new Response("Done!"); | ||
}, | ||
}); | ||
``` | ||
Pass `0` to disable the timeout for a request. | ||
### server.requestIP(Request) - Get client information | ||
Get client IP and port information: | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req, server) { | ||
const address = server.requestIP(req); | ||
if (address) { | ||
return new Response( | ||
`Client IP: ${address.address}, Port: ${address.port}`, | ||
); | ||
} | ||
return new Response("Unknown client"); | ||
}, | ||
}); | ||
``` | ||
Returns `null` for closed requests or Unix domain sockets. | ||
## Server Metrics | ||
### server.pendingRequests and server.pendingWebSockets | ||
Monitor server activity with built-in counters: | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req, server) { | ||
return new Response( | ||
`Active requests: ${server.pendingRequests}\n` + | ||
`Active WebSockets: ${server.pendingWebSockets}`, | ||
); | ||
}, | ||
}); | ||
``` | ||
### server.subscriberCount(topic) - WebSocket subscribers | ||
Get count of subscribers for a WebSocket topic: | ||
```ts | ||
const server = Bun.serve({ | ||
fetch(req, server) { | ||
const chatUsers = server.subscriberCount("chat"); | ||
return new Response(`${chatUsers} users in chat`); | ||
}, | ||
websocket: { | ||
message(ws) { | ||
ws.subscribe("chat"); | ||
}, | ||
}, | ||
}); | ||
``` | ||
## WebSocket Configuration | ||
### server.publish(topic, data, compress) - WebSocket Message Publishing | ||
The server can publish messages to all WebSocket clients subscribed to a topic: | ||
```ts | ||
const server = Bun.serve({ | ||
websocket: { | ||
message(ws) { | ||
// Publish to all "chat" subscribers | ||
server.publish("chat", "Hello everyone!"); | ||
}, | ||
}, | ||
fetch(req) { | ||
// ... | ||
}, | ||
}); | ||
``` | ||
The `publish()` method returns: | ||
- Number of bytes sent if successful | ||
- `0` if the message was dropped | ||
- `-1` if backpressure was applied | ||
### WebSocket Handler Options | ||
When configuring WebSockets, several advanced options are available through the `websocket` handler: | ||
```ts | ||
Bun.serve({ | ||
websocket: { | ||
// Maximum message size (in bytes) | ||
maxPayloadLength: 64 * 1024, | ||
// Backpressure limit before messages are dropped | ||
backpressureLimit: 1024 * 1024, | ||
// Close connection if backpressure limit is hit | ||
closeOnBackpressureLimit: true, | ||
// Handler called when backpressure is relieved | ||
drain(ws) { | ||
console.log("Backpressure relieved"); | ||
}, | ||
// Enable per-message deflate compression | ||
perMessageDeflate: { | ||
compress: true, | ||
decompress: true, | ||
}, | ||
// Send ping frames to keep connection alive | ||
sendPings: true, | ||
// Handlers for ping/pong frames | ||
ping(ws, data) { | ||
console.log("Received ping"); | ||
}, | ||
pong(ws, data) { | ||
console.log("Received pong"); | ||
}, | ||
// Whether server receives its own published messages | ||
publishToSelf: false, | ||
}, | ||
}); | ||
``` | ||
## Benchmarks | ||
@@ -565,57 +800,110 @@ | ||
```ts | ||
interface Bun { | ||
serve(options: { | ||
development?: boolean; | ||
error?: ( | ||
request: ErrorLike, | ||
) => Response | Promise<Response> | undefined | Promise<undefined>; | ||
fetch(request: Request, server: Server): Response | Promise<Response>; | ||
hostname?: string; | ||
id?: string | null; | ||
maxRequestBodySize?: number; | ||
port?: string | number; | ||
reusePort?: boolean; | ||
tls?: TLSOptions | Array<TLSOptions>; | ||
unix: string; | ||
websocket: WebSocketHandler<WebSocketDataType>; | ||
}): Server; | ||
} | ||
interface Server extends Disposable { | ||
/** | ||
* Stop the server from accepting new connections. | ||
* @param closeActiveConnections If true, immediately terminates all connections | ||
* @returns Promise that resolves when the server has stopped | ||
*/ | ||
stop(closeActiveConnections?: boolean): Promise<void>; | ||
interface TLSOptions { | ||
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile> | undefined; | ||
cert?: | ||
| string | ||
| Buffer | ||
| BunFile | ||
| Array<string | Buffer | BunFile> | ||
| undefined; | ||
dhParamsFile?: string; | ||
key?: | ||
| string | ||
| Buffer | ||
| BunFile | ||
| Array<string | Buffer | BunFile> | ||
| undefined; | ||
lowMemoryMode?: boolean; | ||
passphrase?: string; | ||
secureOptions?: number | undefined; | ||
serverName?: string; | ||
/** | ||
* Update handlers without restarting the server. | ||
* Only fetch and error handlers can be updated. | ||
*/ | ||
reload(options: Serve): void; | ||
/** | ||
* Make a request to the running server. | ||
* Useful for testing or internal routing. | ||
*/ | ||
fetch(request: Request | string): Response | Promise<Response>; | ||
/** | ||
* Upgrade an HTTP request to a WebSocket connection. | ||
* @returns true if upgrade successful, false if failed | ||
*/ | ||
upgrade<T = undefined>( | ||
request: Request, | ||
options?: { | ||
headers?: Bun.HeadersInit; | ||
data?: T; | ||
}, | ||
): boolean; | ||
/** | ||
* Publish a message to all WebSocket clients subscribed to a topic. | ||
* @returns Bytes sent, 0 if dropped, -1 if backpressure applied | ||
*/ | ||
publish( | ||
topic: string, | ||
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, | ||
compress?: boolean, | ||
): ServerWebSocketSendStatus; | ||
/** | ||
* Get count of WebSocket clients subscribed to a topic. | ||
*/ | ||
subscriberCount(topic: string): number; | ||
/** | ||
* Get client IP address and port. | ||
* @returns null for closed requests or Unix sockets | ||
*/ | ||
requestIP(request: Request): SocketAddress | null; | ||
/** | ||
* Set custom idle timeout for a request. | ||
* @param seconds Timeout in seconds, 0 to disable | ||
*/ | ||
timeout(request: Request, seconds: number): void; | ||
/** | ||
* Keep process alive while server is running. | ||
*/ | ||
ref(): void; | ||
/** | ||
* Allow process to exit if server is only thing running. | ||
*/ | ||
unref(): void; | ||
/** Number of in-flight HTTP requests */ | ||
readonly pendingRequests: number; | ||
/** Number of active WebSocket connections */ | ||
readonly pendingWebSockets: number; | ||
/** Server URL including protocol, hostname and port */ | ||
readonly url: URL; | ||
/** Port server is listening on */ | ||
readonly port: number; | ||
/** Hostname server is bound to */ | ||
readonly hostname: string; | ||
/** Whether server is in development mode */ | ||
readonly development: boolean; | ||
/** Server instance identifier */ | ||
readonly id: string; | ||
} | ||
interface WebSocketHandler<T = undefined> { | ||
/** Maximum WebSocket message size in bytes */ | ||
maxPayloadLength?: number; | ||
/** Bytes of queued messages before applying backpressure */ | ||
backpressureLimit?: number; | ||
close?( | ||
ws: ServerWebSocket<T>, | ||
code: number, | ||
reason: string, | ||
): void | Promise<void>; | ||
/** Whether to close connection when backpressure limit hit */ | ||
closeOnBackpressureLimit?: boolean; | ||
/** Called when backpressure is relieved */ | ||
drain?(ws: ServerWebSocket<T>): void | Promise<void>; | ||
/** Seconds before idle timeout */ | ||
idleTimeout?: number; | ||
maxPayloadLength?: number; | ||
message( | ||
ws: ServerWebSocket<T>, | ||
message: string | Buffer, | ||
): void | Promise<void>; | ||
open?(ws: ServerWebSocket<T>): void | Promise<void>; | ||
/** Enable per-message deflate compression */ | ||
perMessageDeflate?: | ||
@@ -627,35 +915,56 @@ | boolean | ||
}; | ||
/** Send ping frames to keep connection alive */ | ||
sendPings?: boolean; | ||
/** Whether server receives its own published messages */ | ||
publishToSelf?: boolean; | ||
/** Called when connection opened */ | ||
open?(ws: ServerWebSocket<T>): void | Promise<void>; | ||
/** Called when message received */ | ||
message( | ||
ws: ServerWebSocket<T>, | ||
message: string | Buffer, | ||
): void | Promise<void>; | ||
/** Called when connection closed */ | ||
close?( | ||
ws: ServerWebSocket<T>, | ||
code: number, | ||
reason: string, | ||
): void | Promise<void>; | ||
/** Called when ping frame received */ | ||
ping?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>; | ||
/** Called when pong frame received */ | ||
pong?(ws: ServerWebSocket<T>, data: Buffer): void | Promise<void>; | ||
publishToSelf?: boolean; | ||
sendPings?: boolean; | ||
} | ||
interface Server { | ||
fetch(request: Request | string): Response | Promise<Response>; | ||
publish( | ||
compress?: boolean, | ||
data: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer, | ||
topic: string, | ||
): ServerWebSocketSendStatus; | ||
ref(): void; | ||
reload(options: Serve): void; | ||
requestIP(request: Request): SocketAddress | null; | ||
stop(closeActiveConnections?: boolean): void; | ||
unref(): void; | ||
upgrade<T = undefined>( | ||
options?: { | ||
data?: T; | ||
headers?: Bun.HeadersInit; | ||
}, | ||
request: Request, | ||
): boolean; | ||
interface TLSOptions { | ||
/** Certificate authority chain */ | ||
ca?: string | Buffer | BunFile | Array<string | Buffer | BunFile>; | ||
readonly development: boolean; | ||
readonly hostname: string; | ||
readonly id: string; | ||
readonly pendingRequests: number; | ||
readonly pendingWebSockets: number; | ||
readonly port: number; | ||
readonly url: URL; | ||
/** Server certificate */ | ||
cert?: string | Buffer | BunFile | Array<string | Buffer | BunFile>; | ||
/** Path to DH parameters file */ | ||
dhParamsFile?: string; | ||
/** Private key */ | ||
key?: string | Buffer | BunFile | Array<string | Buffer | BunFile>; | ||
/** Reduce TLS memory usage */ | ||
lowMemoryMode?: boolean; | ||
/** Private key passphrase */ | ||
passphrase?: string; | ||
/** OpenSSL options flags */ | ||
secureOptions?: number; | ||
/** Server name for SNI */ | ||
serverName?: string; | ||
} | ||
@@ -662,0 +971,0 @@ ``` |
@@ -113,3 +113,3 @@ Spawn child processes with `Bun.spawn` or `Bun.spawnSync`. | ||
const text = await new Response(proc.stdout).text(); | ||
console.log(text); // => "bun-v1.2.1" | ||
console.log(text); // => "1.2.2-canary.20250201T140531" | ||
``` | ||
@@ -116,0 +116,0 @@ |
@@ -9,3 +9,3 @@ As of Bun v1.1.44, we've added initial support for bundling frontend apps directly in Bun's HTTP server: `Bun.serve()`. Run your frontend and backend in the same app with no extra steps. | ||
Bun.serve({ | ||
const server = Bun.serve({ | ||
// Add HTML imports to `static` | ||
@@ -36,2 +36,4 @@ static: { | ||
}); | ||
console.log(`Listening on ${server.url}`) | ||
``` | ||
@@ -112,3 +114,3 @@ | ||
```ts#src/backend.ts | ||
import dashboard from "./public/dashboard.html"; | ||
import dashboard from "../public/dashboard.html"; | ||
import { serve } from "bun"; | ||
@@ -210,8 +212,10 @@ | ||
For example, enable TailwindCSS on your routes by adding add the `bun-plugin-tailwind` plugin: | ||
For example, enable TailwindCSS on your routes by installing and adding the `bun-plugin-tailwind` plugin: | ||
```toml | ||
```sh | ||
$ bun add bun-plugin-tailwind | ||
``` | ||
```toml#bunfig.toml | ||
[serve.static] | ||
plugins = ["bun-plugin-tailwind"] | ||
``` | ||
@@ -221,4 +225,3 @@ | ||
```html | ||
<!-- index.html --> | ||
```html#index.html | ||
<!doctype html> | ||
@@ -238,10 +241,11 @@ <html> | ||
```css | ||
/* style.css */ | ||
```css#style.css | ||
@import "tailwindcss"; | ||
``` | ||
### Custom plugins | ||
Any JS file or module which exports a [valid bundler plugin object](https://bun.sh/docs/bundler/plugins#usage) (essentially an object with a `name` and `setup` field) can be placed inside the `plugins` array: | ||
```toml | ||
```toml#bunfig.toml | ||
[serve.static] | ||
@@ -248,0 +252,0 @@ plugins = ["./my-plugin-implementation.ts"] |
@@ -10,3 +10,3 @@ Use `bun publish` to publish a package to the npm registry. | ||
## Output | ||
bun publish vbun-v1.2.1 (ca7428e9) | ||
bun publish v1.2.2-canary.20250201T140531 (ca7428e9) | ||
@@ -13,0 +13,0 @@ packed 203B package.json |
@@ -101,3 +101,3 @@ --- | ||
const db = drizzle(sqlite); | ||
await migrate(db, { migrationsFolder: "./drizzle" }); | ||
migrate(db, { migrationsFolder: "./drizzle" }); | ||
``` | ||
@@ -104,0 +104,0 @@ |
@@ -38,3 +38,3 @@ --- | ||
+ with: | ||
+ bun-version: 1.0.11 # or "latest", "canary", <sha> | ||
+ bun-version: 1.2.0 # or "latest", "canary", <sha> | ||
``` | ||
@@ -41,0 +41,0 @@ |
@@ -127,7 +127,7 @@ --- | ||
```sh | ||
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/bun-v1.2.1" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}" | ||
[fetch] $ curl --http1.1 "https://example.com/" -X POST -H "content-type: application/json" -H "Connection: keep-alive" -H "User-Agent: Bun/1.2.2-canary.20250201T140531" -H "Accept: */*" -H "Host: example.com" -H "Accept-Encoding: gzip, deflate, br" --compressed -H "Content-Length: 13" --data-raw "{\"foo\":\"bar\"}" | ||
[fetch] > HTTP/1.1 POST https://example.com/ | ||
[fetch] > content-type: application/json | ||
[fetch] > Connection: keep-alive | ||
[fetch] > User-Agent: Bun/bun-v1.2.1 | ||
[fetch] > User-Agent: Bun/1.2.2-canary.20250201T140531 | ||
[fetch] > Accept: */* | ||
@@ -174,3 +174,3 @@ [fetch] > Host: example.com | ||
[fetch] > Connection: keep-alive | ||
[fetch] > User-Agent: Bun/bun-v1.2.1 | ||
[fetch] > User-Agent: Bun/1.2.2-canary.20250201T140531 | ||
[fetch] > Accept: */* | ||
@@ -177,0 +177,0 @@ [fetch] > Host: example.com |
@@ -58,3 +58,3 @@ Bun's test runner plays well with existing component and DOM testing libraries, including React Testing Library and [`happy-dom`](https://github.com/capricorn86/happy-dom). | ||
$ bun test | ||
bun test vbun-v1.2.1 | ||
bun test v1.2.2-canary.20250201T140531 | ||
@@ -61,0 +61,0 @@ dom.test.ts: |
{ | ||
"version": "1.2.1", | ||
"version": "1.2.2-canary.20250201T140531", | ||
"name": "bun-types", | ||
@@ -4,0 +4,0 @@ "license": "MIT", |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
1380982
0.89%1
Infinity%