bun-in-browser
v0.1.0
Published
Run Bun.js-style servers in the browser with a WebSocket-based reverse proxy
Downloads
11
Maintainers
Readme
bun-in-browser
Run Bun.js-style servers in the browser with a WebSocket-based reverse proxy.
Installation
bun add bun-in-browser
Usage
Public WebSocket Service
bun-in-browser offers a public WebSocket service that is recommended for most use cases:
- URL:
wss://browser-proxy.web4.near.page
- This service allows you to run your bun-in-browser applications without setting up your own server.
- When you connect to this WebSocket, your application becomes available at a unique subdomain of
web4.near.page
. - Example: If your client ID is "abc123", your site would be accessible at
https://abc123.web4.near.page
.
Use this public WebSocket service unless you expect heavy load for your application.
Self-hosted Server
If you need to run your own server (e.g., for high-load applications), you can do so using the provided app.js
script:
PORT=3000 BASE_URL=http://localhost:3000 USE_SUBDOMAINS=false bun app.js
Or use the startReverseProxy
function in your own script:
import { startReverseProxy } from 'bun-in-browser/src/server.js';
const { server, stop } = startReverseProxy({
port: 3000,
baseUrl: 'http://localhost:3000',
useSubdomains: false
});
console.log(`Server started on port 3000. Base URL: http://localhost:3000`);
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log('Received SIGINT. Shutting down gracefully...');
stop();
process.exit(0);
});
Demo
A public demo is available to showcase bun-in-browser capabilities:
- URL: https://outstanding-bee.static.domains
- This demo allows you to experiment with both simple and advanced usage directly in your browser.
To run the demo locally:
bun run demo
After starting the server, navigate to the demo URL provided in the console output (typically http://localhost:3001).
Simple Demo
The simple demo (View Source) demonstrates basic routing and JSON responses. Here's an example of the client-side code:
import { BunInBrowser } from 'bun-in-browser/client';
const bunInBrowser = new BunInBrowser('wss://browser-proxy.web4.near.page');
const serverModule = {
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/") {
return new Response("Hello from Bun.js in the browser!");
}
if (url.pathname === "/json") {
return Response.json({ message: "This is JSON data" });
}
return new Response("Not Found", { status: 404 });
},
};
bunInBrowser.serverModule = serverModule;
Advanced Demo
The advanced demo (View Source) showcases a more complex application: a guest book. It demonstrates handling different routes, processing form submissions, and generating dynamic HTML responses. Here's an excerpt from the demo:
const serverModule = {
guestBook: [],
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/") {
return new Response(this.renderGuestBook(), {
headers: { "Content-Type": "text/html" }
});
}
if (url.pathname === "/sign" && req.method === "POST") {
return this.handleSignGuestBook(req);
}
if (url.pathname === "/api") {
return Response.json({
message: "This is a JSON response from Bun.js",
clientId: window.clientId,
clientUrl: window.clientUrl
});
}
return new Response("Not Found", { status: 404 });
},
renderGuestBook() {
let html = `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
<h1 style="color: #333;">Welcome to our Guest Book!</h1>
<form action='/sign' method='POST' style="margin-bottom: 20px;">
<input type='text' name='name' placeholder='Your Name' required style="margin: 5px 0; padding: 5px;">
<input type='text' name='message' placeholder='Your Message' required style="margin: 5px 0; padding: 5px;">
<button type='submit' style="margin: 5px 0; padding: 5px; background-color: #4CAF50; color: white; border: none; cursor: pointer;">Sign Guest Book</button>
</form>
<h2>Entries:</h2>
<ul style="list-style-type: none; padding: 0;">
${this.guestBook.map(entry => `<li style="margin-bottom: 10px;"><strong>${entry.name}</strong>: ${entry.message}</li>`).join('')}
</ul>
</div>
`;
return html;
},
async handleSignGuestBook(req) {
const formData = await req.formData();
const name = formData.get("name");
const message = formData.get("message");
this.guestBook.push({ name, message });
return new Response("Entry added successfully", {
status: 302,
headers: { "Location": "/" }
});
}
};
const bunInBrowser = new BunInBrowser('wss://browser-proxy.web4.near.page', serverModule);
API
Client-side
new BunInBrowser(wsUrl, serverModule)
Creates a new BunInBrowser instance.
wsUrl
: The WebSocket URL to connect to (usewss://browser-proxy.web4.near.page
for the public service)serverModule
: (Optional) The server module object
bunInBrowser.serverModule
Set this property to your Bun.js server module object. The module should have:
fetch(req)
: A function that handles incoming requests and returns a Response object
bunInBrowser.waitUntilReady()
Returns a promise that resolves when the BunInBrowser instance is ready to use.
bunInBrowser.close()
Closes the WebSocket connection.
bunInBrowser.clientId
The unique identifier for this client.
bunInBrowser.clientUrl
The URL where this client's server can be accessed.
Server-side
startReverseProxy(options)
Starts the reverse proxy server.
options.port
: The port for the server (default: 3000)options.baseUrl
: The base URL for the server (default: 'http://localhost:3000')options.useSubdomains
: Whether to use subdomains for client identification (default: false)
Returns an object with:
server
: The server instancestop()
: Function to stop the server
Features
- Run Bun.js-style servers in the browser
- WebSocket-based communication between browser and server
- Public WebSocket service for easy deployment
- Support for various HTTP methods (GET, POST, etc.)
- JSON response handling
- HTML response generation
- Form data processing
- Custom status codes and headers
- Optional subdomain-based client identification
- Environment variable configuration
- Graceful shutdown handling
- Interactive demo with editable code
Development
To run tests:
bun test
Debugging
This project uses the debug
package for logging. To enable debug logs, set the DEBUG environment variable:
DEBUG=bun-in-browser:* bun run your-script.js
For running tests with debug logs:
DEBUG=test:client bun test
Environment Variables
When using the app.js
script, you can configure the server using the following environment variables:
PORT
: The port number for the server (default: 3000)BASE_URL
: The base URL for the server (default:http://localhost:${PORT}
)USE_SUBDOMAINS
: Whether to use subdomains for client identification (default: false)
Note: When using startReverseProxy
directly, the default baseUrl
is the fixed string 'http://localhost:3000'.
License
MIT