Blog

Unrestricted Browser Networking: Raw TCP Sockets, Modern TLS, and CORS-Free HTTP

For decades, web developers have been constrained by the browser's networking limitations. Need an FTP API? It doesn't exist in the browser. Want to build an SSH client? Can't access raw TCP sockets. Need to fetch data from any API? CORS says no. The browser does not support raw TCP sockets, and the only way to access them is to use a proxy, which is slow and insecure.

That's why we built something different.

Today, we're excited to announce Puter Networking - a complete networking stack that brings unrestricted, secure networking capabilities directly to your frontend code, powered by Puter.js, requiring no API keys, no configuration, and no servers. From raw TCP sockets to modern TLS encryption, and CORS-free HTTP requests, Puter.js Networking opens up a whole new world of possibilities for web developers, previously impossible.

Before diving into the technical details, let's briefly explain the platform that makes this possible.

What is Puter.js?

Puter.js is a frontend library that brings serverless auth, cloud, and AI services directly to your browser-side JavaScript with no backend code or configuration required. It offers, among other things, authentication, cloud storage, and AI services. Puter.js is powered by Puter, an open-source, self-hostable cloud computing platform.

https://super-magical-website.com
OpenAI
Cloud Storage
Anthropic
DALLĀ·E 3
NoSQL

<script src="https://js.puter.com/v2/"></script>

Networking
Auth
UI Components
Text to Image
Text to Speech

Puter.js Networking is a new collection of networking-related APIs inside of Puter.js, allowing you to create Socket connections, support fully compliant TLS connections, and fetch HTTP resources as if you were writing server-side code.

Examples

The following are some simple examples of Puter.js Networking, demonstrating how to create a TCP socket, fetch an HTTP resource, and use modern TLS encryption. Let's start with the fundamentals and work our way up to more advanced networking concepts:

plug-2 Raw TCP Sockets

Create direct TCP connections from your browser to any server on the internet. Build SSH clients, FTP applications, or implement any custom protocol - all running client-side.

<html>
<body>
  <script src="https://js.puter.com/v2/"></script>
  <script>
      // Open a TCP socket to any server
      const socket = new puter.net.Socket('example.com', 80);
      
      // Write a HTTP request to the socket
      socket.on("open", () => {
        socket.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
      });

      // Log the response from the server
      socket.on('data', (data) => {
        puter.print(data, {code: true});
      });
  </script>
</body>
</html>

lockModern TLS Encryption

Layer modern, secure TLS encryption on top of your TCP streams. Unlike outdated browser libraries, we support the latest TLS versions with full security compliance.

// Add modern TLS encryption to any socket
const tlsSocket = new puter.net.tls.TLSSocket('example.com', 443);

// Write a HTTP request to the socket
tlsSocket.on("open", () => {
    tlsSocket.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n");
});

// Log the response from the server
tlsSocket.on('data', (data) => {
    puter.print(data, {code: true});
});

world-2 CORS-Free HTTP(S)

Make HTTP requests to any server without CORS restrictions. Unlike traditional CORS proxies, your data stays encrypted end-to-end - our servers never see your traffic. Use puter.net.fetch() as a drop-in replacement for browser's fetch, without the restrictions of CORS.

// Send a GET request to example.com
const request = await puter.net.fetch("https://example.com");        

// Get the response body as text
const body = await request.text();

// Print the body as a code block
puter.print(body, { code: true });



These 3 fundamental APIs are all you need to build any powerful network application in the browser. To see these capabilities in action, we've listed a few demo applications that showcase what's possible with puter.net:

  • Browser: A browser!
  • API Tester: A simple alternative to Postman/Insomnia.
  • Scraper: A simple web scraper to scrape websites using CSS selectors.

Now that you've seen what's possible, let's explore how we made this work under the hood.

Behind the scenes

What exactly is the internet?

The internet in essence is just a network of computers connected by TCP/IP. TCP is the foundation of most of the protocols you use in the browser, be it HTTP, HTTPS, SSH, FTP, or pretty much every non-gaming protocol on the internet (those typically use UDP/IP instead, a protocol which prioritizes speed over reliability of data). This means that network applications usually use TCP to communicate with other computers on the internet. So if you wanted to build, for example, an SSH client, you would need to use TCP to connect to the SSH server. Same goes for FTP, HTTP, and so on.

Doesn't my browser already do that?

Your browser does handle TCP connections (every website you visit is over HTTP or HTTPS), but it severely restricts what websites other websites can access. You can't simply run fetch("https://google.com") from puter or any other site because of a concept called "CORS." CORS is a restrictive policy that allows sites to control what other sites can access their data from the front end. Furthermore, while there are user-facing APIs for accessing content and resources over HTTP/S, there are none for making a TCP stream directly. This means it's impossible to make an SSH or FTP client fully in the front end, for example.

"So, just proxy the TCP!"

That seems like the obvious next step, and indeed several projects try to do exactly that. One notable example is Websockify, which turns a TCP stream into a WebSocket channel. But this approach suffers from several issues: the destination has to be hardcoded, each TCP stream requires a separate WebSocket connection, and establishing WebSocket connections for every new socket is not only slow but also places unnecessary load on the server for apps that need multiple TCP sockets. Even if you overlook those points, you still run into the problem of TLS. The foundational encryption behind HTTPS cannot be used inside the browser for your own data streams. The only widespread library, Forge-TLS, supports only up to TLS 1.1, an outdated and insecure protocol version that has long been discontinued.

Our solution: A unified networking API

puter.net is a collection of networking-related APIs inside of Puter, allowing you to create Socket connections, support fully compliant TLS connections, and fetch HTTP resources as if you were writing server-side code. With puter.net.Socket, you can open raw TCP streams; with puter.net.tls.TLSSocket, you can layer modern TLS on top of those streams; and with puter.net.fetch, you can retrieve HTTP(S) resources using in browser encryption to the end server. Unlike a cors proxy, the relay server here can't see what data is being fetched since encryption is done from your client to the end server which hosts the resource being accessed.

The TCP/UDP proxy: Wisp

Wisp is a protocol for multiplexing multiple streams over a single WebSocket. It natively supports TCP, UDP, and even optional PTY streams to serve as an SSH alternative. Puter uses Wisp to proxy TCP data from the frontend to the backend, where it is then forwarded to any host on the internet. In essence, it's like a VPN protocol that works directly in the browser. Unlike other proxies, Wisp supports zero-round-trip creation of streams, which can significantly improve performance on slow networks by eliminating three full round trips for each new socket, sometimes making it even faster than native socket creation.

Because the browser will only allow connections at the WebSocket layer, Wisp encapsulates raw TCP stream data within its own multiplexing protocol, sends it over a WebSocket, and then unpacks the data on the server, forwarding it to the intended destination.

Encryption

The browser may handle TLS for its own connections, but it will not encrypt arbitrary data you send over custom protocols. Since Wisp operates one layer above TCP, on what is effectively the session layer, the browser won't provide any encryption. If you simply piped your data through Wisp, it would be sent in the clear.

Enter Rustls-wasm

Rustls-wasm is a WebAssembly port of rustls, a Rust-based TLS library that uses Ring for cryptographic operations. Think of it as a lightweight, browser-native equivalent to OpenSSL. By integrating Rustls-wasm into Puter, we can apply modern TLS encryption to our proxied socket connections in exactly the same way the browser encrypts its own HTTP/S traffic, but several layers higher. This lets you establish fully secure TLS sessions over raw TCP streams that travel through Wisp, giving you first-class security and performance inside the browser.

Puter.js rustls wisp diagram

A complete diagram of a request to https://example.com

What it all means

In effect, by combining Wisp's efficient multiplexed proxying and Rustls-wasm's up-to-date TLS implementation, we can bring unrestricted but secure networking (including raw TCP/IP sockets) into the browser's sandboxed environment. This approach opens up many opportunities allowing developers to create advanced applications using TCP directly in the browser with no encryption invading external proxies, outdated libraries, or any compromises.

Let's get started!

We're incredibly excited to see what you'll build with unrestricted networking in the browser. From SSH clients to API testing tools, from real-time monitoring dashboards to custom protocol implementations, the possibilities are endless, and we can't wait to see your creations.

And remember, networking is just one part of the Puter.js ecosystem. The same simple <script> tag also gives you access to authentication, cloud storage, AI services, UI components, and much more, everything you need to build complete applications entirely in the frontend.

Related

Ready to Build Your First App?

Start creating powerful web applications with Puter.js today!

Get Started Now

Read the Docs Try the Playground