How to Make an Ultraviolet Proxy

Ultraviolet proxy

Ultraviolet is a highly advanced web proxy used for evading internet censorship or accessing websites in a controlled sandbox. It is designed with security and performance in mind. Ultraviolet intercepts HTTP requests with a service worker, while adhering to the TompHTTP specifications and is a leader in innovative web proxy technologies.


Ultraviolet offers several features that set it apart from its predecessors, including CAPTCHA and hCAPTCHA support, URL encoding settings for added security, client-side configuration via service workers, high speed compared to other web proxies, blacklist settings and more for easy hosting, leak prevention, regular updates, and improved resource usage and speed for better setups with a dedicated server instance.

Supported Sites

Some of the popular websites that Ultraviolet supports include:

  • Google
  • Youtube
  • Spotify
  • Discord
  • Reddit
  • GeForce NOW
Used by
  • Alu
  • AnuraOS
  • Nebula
  • Holy Unblocker
  • Terbium
  • Incognito
  • Metallic

Older Ultraviolet versions:

Starting from v3, Ultraviolet uses bare-mux, a library that allows you to switch out your Bare client.

If you operate using an older Ultraviolet, we encourage you to update.

If you're too lazy to do either of the above, you can install an outdated and unsupported version of Ultraviolet.

npm install @titaniumnetwork-dev/ultraviolet@1

Ultraviolet-App - Deployable all-in-one bundle

The deployable all-in-one bundle for Ultraviolet, a highly sophisticated proxy used for evading internet censorship or accessing websites in a controlled sandbox using the power of service workers and more!

If you are deploying to an alternative service or to a server, refer to Deploy via terminal.

Deploy via terminal

Deploying Ultraviolet through a terminal is quite an easy process.

If you opened this repository in Replit:

You can skip the clone steps and directly start with the install process. Use the Replit terminal instead of the console by selecting "Shell" under tools or selecting the "Shell" tab in the Replit terminal


1. Clone

git clone
cd Ultraviolet-App

2. Install

npm install
//If this takes long, you may attempt to omit dev dependencies:
npm install --omit=dev

3. Start

Once dependencies are installed, select the "Run" button on Replit or run:

npm start

Alternatively, run on a port:

PORT=8080 npm start

You can stop it at any time by pressing CTRL + C

Important Note! Until deployed on a domain with a valid SSL certificate, Firefox will not be able to load the site. Use chromium for testing on localhost

Customizing your frontend

You can also customize the front end of the app.

The static files (frontend) are generated in the Ultraviolet-Static repository. You can follow the instructions within the repository to modify the frontend here.

Follow the instructions for deployment guided above. The following steps assume you are in a directory containing the content of Ultraviolet-App.

1. Clone Ultraviolet-Static

git clone
cd Ultraviolet-Static

2. Install dependencies

npm install

3. Make your changes

You may go back to this step anytime, however we recommend you make your changes before applying them.

The content inside Ultraviolet-Static/public/ may be modified. This directory contains assets and HTML web pages.

4. Install the modified module

You should only have to do this once. Any future changes  Ultraviolet-Static/public/ will immediately take effect.

Enter the Ultraviolet-App directory:

cd ..

Install the new module:

npm install ./Ultraviolet-Static

5. Start

npm start

Tips! Check the guide for Fixing SSL errors for Ultraviolet: Configure SSL

How to Set Up Ultraviolet in Your Own Proxy

This guide covers the setup of Ultraviolet (UV), including creating a new frontend or integrating an existing one. If you need assistance, feel free to DM me on Discord @crllect.

Step 1: Download the Template

Start by downloading the template available in this repository.

Step 2: Clone Ultraviolet

Clone the most recent version of Ultraviolet from here. You can either build it yourself or download the .tgz file.

Unzip the downloaded file. (Note that on Windows, you can't extract .tgz files without win-rar, 7zip or any other program.

Search up "tgz to zip" online, and then convert it to zip so you can extract it)

Inside the dist directory (titaniumnetwork-dev-ultraviolet-x.x.x/package/dist), download all .js files and place them in public/uv.

Note! The author has attached his own modified UV files, but they may be out of date. If you don't want to clone and build everything, just use my files

Step 3: Adding Frontend

Place all your frontend code, including assets, inside the public directory of the template.

  • Note: The .gitignore in the template already excludes node modules. Or you can follow the above steps also.
  • Open the server.js file in the template and modify it according to the instructions provided in the file.

Step 4: Frontend Integration

In your HTML, add the following to <head>

<script src="/uv/uv.bundle.js"></script>
<script src="/uv/uv.config.js"></script>
  if ("serviceWorker" in navigator) {
    window.addEventListener("load", () => {
      navigator.serviceWorker.register("/uv/sw.js", {
        scope: __uv$config.prefix,

Now, if you know what you're doing, in your JS, all you need to do is this:location.href = __uv$config.prefix + __uv$config.encodeUrl(url);

If that doesn't make sense, it's okay.

Start off by having an iframe window with no src. Add the class and iframeWindow, you can name it something else, but change the JS appropriately.

<iframe id="iframeWindow" class="iframeWindow"></iframe>

Then add a text input to your HTML:

<input type="text" id="urlInput" placeholder="Enter URL here">

<button id="searchButton">Search Text</button>

add this to your JS, if you changed the class or ID name, change it in here too:

document // makes it so you can press enter to submit as opposed to just being able to press a button
    .addEventListener("keydown", function (event) {
        if (event.key === "Enter") {

document.getElementById("searchButton").onclick = function (event) {

    let url = document.getElementById("urlInput").value; // if no periods are detected in the input, search google instead
    let searchUrl = "";

    if (!url.includes(".")) {
        url = searchUrl + encodeURIComponent(url);
    } else {
        if (!url.startsWith("http://") && !url.startsWith("https://")) { // if no http or https is detected, add https automatically
            url = "https://" + url;

    iframeWindow.src = __uv$config.prefix + __uv$config.encodeUrl(url);

Step 5: Building It

Only do this the first time:

  1. Open a terminal in the directory of your project in VSCode, this is as easy and ctrl-shift-C on your project, and run npm i @tomphttp/bare-server-node express
      • Note! Renaming the template after running the next command will cause it to stop working. Rename the template to your repository name before running npm i @tomphttp/bare-server-node express. If you want to rename it after uninstall using npm or delete the package files and the node_modules directory

  2. Add "type": "module" to package.json. Example:


  "dependencies": {
    "@tomphttp/bare-server-node": "^2.0.1",
    "express": "^4.18.2"


  "dependencies": {
    "@tomphttp/bare-server-node": "^2.0.1",
    "express": "^4.18.2"
  "type": "module"

Note: don't forget the comma after the ending curly bracket of dependencies

Every time you start it up: You can start it by typing node server.js into the terminal window, you can now visit it locally by typing localhost:Port into a web browser

Note: The default port is 8080

Step 6: Deploying It

There are infinitely many ways to do this, replit does not have any form of proxies, and has spotty uptime, so that will usually be a no-go. Many hosts such as Vercel and Cloudflare are static hosts, meaning they can't support the backend logic required for UltraViolet. Solution: A solution I have found is to use either bare metal or cheap online service to host the bare server and something like Cloudflare or vercel to host the frontend

Note: If you end up using two separate services for the front end and back end, then you need to go to public/uv/uv.config.js and change the bare server to your bare server. Example:

/*global Ultraviolet*/
self.__uv$config = {
    prefix: '/uv/service/',
    bare: 'INSERT YOUR BARE SERVER HERE, IF IN THE SAME SERVICE AS FRONTEND PUT: /bare/ IF AN EXTERNAL SERVICE: https://link.external.service/bare/',
    encodeUrl: Ultraviolet.codec.xor.encode,
    decodeUrl: Ultraviolet.codec.xor.decode,
    handler: '/uv/uv.handler.js',
    client: '/uv/uv.client.js',
    bundle: '/uv/uv.bundle.js',
    config: '/uv/uv.config.js',
    sw: '/uv/uv.sw.js',

Check out Ultraviolet Proxy codes

Ultraviolet Ultraviolet-App